线段树入门之单点更新

这里写链接内容

#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