线段树(Segment Tree)与树状数组(Binary Indexed Tree)两种写法
ST为单点更新
以后能用BIT写的还是用BIT吧。。
///ST
#include <stdio.h>
#include <string.h>
const int MAXN = 50005;
int save[MAXN];
struct ST
{
int left,right,mid,val;
}node[3*MAXN];
void make(int l,int r,int num)
{
node[num].left = l ;
node[num].right= r ;
node[num].mid = (l+r)>>1;
if(r==l)
return;
make(l,node[num].mid,num<<1);
make(node[num].mid+1,r,num<<1|1);
}
void insert(int pos,int val,int num)
{
node[num].val+=val;
//printf("pos:%d\n",pos);
//printf("num:%d\t%d\t%d\nval:%d\n",num,node[num].left,node[num].right,node[num].val);
if(node[num].left==pos&&node[num].right==pos)
return;
if(pos<=node[num].mid)
insert(pos,val,num<<1);
else
insert(pos,val,num<<1|1);
}
int cal(int l,int r,int num)
{
/*printf("num:%d\t%d\t%d\nval:%d\n",num,node[num].left,node[num].right,node[num].val);
printf("LR:%d\t%d\n",l,r);
puts("");*/
if(node[num].left>=l&&node[num].right<=r)
return node[num].val;
if(node[num].left>r||node[num].right<l)
return 0;
return cal(l,r,num<<1)+cal(l,r,num<<1|1);
}
int main()
{
int T,C=1;
scanf("%d",&T);
while(T--)
{
printf("Case %d:\n",C++);
memset(node,0,sizeof(node));
int n;
scanf("%d",&n);
make(1,n,1);
for(int i=0;i<n;i++)
{
scanf("%d",&save[i+1]);
insert(i+1,save[i+1],1);
}
/*for(int i=1;i<=n;i++)
{
printf("*%d\t",node[i].val);
}*/
char com[100];
int a,b;
while(1)
{
scanf("%s",com);
if(com[0]=='E') break;
scanf("%d%d",&a,&b);
if(com[0]=='A')
insert(a,b,1);
else if(com[0]=='S')
insert(a,-b,1);
else if(com[0]=='Q')
printf("%d\n",cal(a,b,1));
}
}
return 0;
}
///BIT
#include <stdio.h>
#include <string.h>
const int MAXN = 50005;
int c[MAXN],n;
int lowbit(int x)
{
return x&(-x);
}
void insert(int pos,int val)
{
while(pos<=n)
{
c[pos]+=val;
pos+=lowbit(pos);
}
}
int cal(int pos)
{
int sum=0;
while(pos>0)
{
sum+=c[pos];
pos-=lowbit(pos);
}
return sum;
}
int main()
{
int T,cnt=1;
scanf("%d",&T);
while(T--)
{
printf("Case %d:\n",cnt++);
memset(c,0,sizeof(c));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int tmp;
scanf("%d",&tmp);
insert(i+1,tmp);
}
char com[20];
int a,b;
while(1)
{
scanf("%s",com);
if(com[0]=='E') break;
scanf("%d%d",&a,&b);
switch (com[0])
{
case 'A':insert(a,b);break;
case 'S':insert(a,-b);break;
case 'Q':printf("%d\n",cal(b)-cal(a-1));break;
}
}
}
return 0;
}