给定区间长度,然后给两个操作,单点增加值和单点减值,询问一个区间的人数和;(水)
代码如下:
/*
写的第一个线段树,丑;
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef struct
{
int l,r;
int value;
}tr[];//长度是区间长度的四倍;
int n,a[]={},ans=;
void build(int i,int l,int r)//建树
{
tr[i].l=l;
tr[i].r=r;
if(l==r)
{
tr[i].value=a[l];
return ;
}
build(i*,l,(l+r)/);
build(i*+,(l+r)/+,r);
tr[i].value=tr[i*].value+tr[i*+].value;
}
void ADD(int i,int l,int x)//区间加值
{
if(tr[i].l==l&&tr[i].r==l)
{
tr[i].value+=x;
return ;
}
int t=i<<;
if(l<=tr[t].r)
ADD(t,l,x);
t+=;
if(l>=tr[t].l)
ADD(t,l,x);
tr[i].value=tr[i<<].value+tr[(i<<)+].value;
}
void SUB(int i,int l,int x)//区间减值
{
if(tr[i].l==l&&tr[i].r==l)
{
tr[i].value-=x;
return ;
}
int t=i<<;
if(l<=tr[t].r)
SUB(t,l,x);
t+=;
if(l>=tr[t].l)
SUB(t,l,x);
tr[i].value=tr[i<<].value+tr[(i<<)+].value;
}
void QUERY(int i,int l,int r)//区间查询寻;
{
if(tr[i].l==l&&tr[i].r==r)
{
ans+=tr[i].value;
return ;
}
i=i<<;
if(l<=tr[i].r)
{
if(r<=tr[i].r)
QUERY(i,l,r);
else
QUERY(i,l,tr[i].r);
}
i+=;
if(r>=tr[i].l)
{
if(l>=tr[i].l)
QUERY(i,l,r);
else
QUERY(i,tr[i].l,r);
}
}
int main()
{
int T,t=;
cin>>T;
while(T--)
{
memset(a,,sizeof(a));
ans=;
cin>>n;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
printf("Case %d:\n",t++);
build(,,n);
char s[];
int x1,x2;
scanf("%s",s);
int k=;
while(s[]!='E')
{
scanf("%d%d",&x1,&x2);
if(s[]=='A')
ADD(,x1,x2);
else if(s[]=='S')
SUB(,x1,x2);
else if(s[]=='Q')
{
QUERY(,x1,x2);
printf("%d\n",ans);
ans=;
}
scanf("%s",s);
}
}
return ;
}