hdu1166

线段树(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;
}


你可能感兴趣的:(线段树,ACM,树状数组,单点更新)