#include<stdio.h>
#include<string.h>
#define MAX 50000
struct node
{
int l,r;
int mid;
int sum;
};
node a[MAX*4];
void BuildTree(int i,int l,int r) //建立线段树
{
a[i].l=l;
a[i].r=r;
if(l==r)
{
scanf("%d",&a[i].sum);
return;
}
a[i].mid=(l+r)/2;
BuildTree(i*2,l,a[i].mid);
BuildTree(i*2+1,a[i].mid+1,r);
a[i].sum=a[i*2].sum+a[i*2+1].sum; //这其实就是我说的那个PushUp(向上更新),这题较简单,向上更新只需要一个语句即可实现,所以就没再写个PushUp函数了
}
void update(int i,int index,int num) //点更新
{
if(a[i].l==a[i].r)
{
a[i].sum+=num;
return;
}
if(a[i].mid>=index)update(i*2,index,num);
if(a[i].mid<index)update(i*2+1,index,num);
a[i].sum=a[i*2].sum+a[i*2+1].sum;
}
int Query(int i,int l,int r) //区间询问
{
if(a[i].l==l&&a[i].r==r)return a[i].sum;
if(r<=a[i].mid)return Query(i*2,l,r);
if(l>a[i].mid)return Query(i*2+1,l,r);
else return Query(i*2,l,a[i].mid)+Query(i*2+1,a[i].mid+1,r);
}
int main()
{
int t,n,i,j;
int a,b;
int count=0;
scanf("%d",&t);
while(t--)
{
count++;
char str[10];
scanf("%d",&n);
BuildTree(1,1,n); //建立线段树
printf("Case %d:\n",count);
while(1)
{
scanf("%s",str);
if(strcmp(str,"Add")==0)
{
scanf("%d%d",&a,&b);
update(1,a,b);
}
else if(strcmp(str,"Sub")==0)
{
scanf("%d%d",&a,&b);
update(1,a,-b); //利用b与-b控制 美观值的增或者减
}
else if(strcmp(str,"Query")==0)
{
scanf("%d%d",&a,&b);
printf("%d\n",Query(1,a,b));
}
else break;
}
}
return 0;
}
线段树入门之单点更新
猜你喜欢
转载自blog.csdn.net/qq_42825221/article/details/82594105
今日推荐
周排行