虽然在大一寒假的时候曾经试过学习线段树,但是后来由于觉得麻烦所以放弃了,现在重新学习线段树,经过这么长时间的锻炼代码的风格也固定了下来,下面是全新的线段树写法,还是这个最经典最裸的线段树单点更新题
#include
#include
#include
using namespace std;
int sum,n;
struct node
{
int l,r,n;
} a[1000000];
void init()//新建一个线段树
{
int i,k;
for(k = 1; k0; i--)
{
a[i].l = a[2*i].l;
a[i].r = a[2*i+1].r;
a[i].n = 0;
}
}
void insert(int i,int x,int m)//线段树的插入
{
if(x>=a[i].l && x<=a[i].r)
a[i].n+=m;
if(a[i].l == a[i].r)
return ;
int mid = (a[i].l+a[i].r)/2;
if(x>mid)
insert(2*i+1,x,m);
else
insert(2*i,x,m);
}
void find(int x,int y,int i)//线段树的查询
{
if(a[i].l == x && a[i].r == y)
{
sum+=a[i].n;
return ;
}
if(a[i].l == a[i].r)
return ;
int mid = (a[i].l+a[i].r)/2;
if(x>mid)
find(x,y,2*i+1);
else if(y<=mid)
find(x,y,2*i);
else
{
find(x,mid,2*i);
find(mid+1,y,2*i+1);
}
}
int main()
{
int t,cas = 1,x,y,i,j,k;
char str[10];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
for(i = 1; i<=n; i++)
{
scanf("%d",&k);
insert(1,i,k);
}
printf("Case %d:\n",cas++);
while(scanf("%s",str) && str[0]!='E')
{
scanf("%d%d",&x,&y);
if(!strcmp(str,"Add"))
insert(1,x,y);
else if(!strcmp(str,"Sub"))
insert(1,x,-y);
else if(!strcmp(str,"Query"))
{
sum = 0;
find(x,y,1);
printf("%d\n",sum);
}
}
}
return 0;
}