hdu-1166 敌兵布阵(线段树的增删查改)

来源:互联网 发布:北塔软件规模 编辑:程序博客网 时间:2024/06/11 06:06

这是我写的第一个线段树题,这种题过程很抽象,代码不容易理解,整整写了三小时,修BUG修了很久,不过还好过了。

思路:这个有点像二分的思想,根节点就是全部兵营,下来的第一个左子结点是全部兵的左半,右子节点是剩下的一半,经过重重递归二分,递归的边界就是只剩一个元素,即左子节点等于右子节点,这样,线段树就构造完成了,增删查改都是通过遍历来找到特定区间或元素,再改变它的值。


下面附上AC代码:

#include<cstdio>#include<string.h>#include<algorithm>#include<cmath>#include<queue>#include<stack>using namespace std;const int N=5e4+10;int str[N];int m,n;int s;struct tree{    int sum,l,r;}node[N*4];void build_tree(int ans,int ll,int rr)//ans是根节点!!!{    if( ll == rr )    {        node[ans].l = node[ans].r = ll;        node[ans].sum = str [ll];        return ;    }    node[ans].l = ll;    node[ans].r = rr;    //printf("Z");    int mid = (ll + rr )>>1;    //printf("C");    build_tree(ans<<1,ll,mid);    build_tree(ans<<1|1,mid+1,rr);    node[ans].sum = node [ans<<1].sum + node[ans<<1|1].sum ;}void update(int ans,int pos,int value)//更新数值{    if(node[ans].l == pos && node[ans].r == pos)    {        node[ans].sum += value ;        return ;    }    int mid = (node[ans].l+node[ans].r)>>1;    if(pos <= mid)    {        update(ans<<1,pos,value);    }    else    {        update(ans<<1|1,pos,value);    }    node[ans].sum = node[ans<<1].sum + node[ans<<1|1].sum ;}void query(int ans,int ll,int rr){    int mid = (node[ans].l+node[ans].r)>>1;    if(node[ans].l == ll && node[ans].r == rr)    {        s += node[ans].sum;        return ;    }    else if( ll > mid )    {        query(ans<<1|1,ll,rr);    }    else if( rr <= mid )    {        query(ans<<1,ll,rr);    }    else    {        query(ans<<1,ll,mid);        query(ans<<1|1,mid+1,rr);    }}int main(){    int t,x,y;    int cas=0;    char ch[10];    scanf("%d",&t);    while(t--)    {        scanf("%d",&m);        for(int i=1;i<=m;i++)            scanf("%d",&str[i]);        printf("Case %d:\n",++cas);        build_tree(1,1,m);        while(~scanf("%s",ch),ch[0]!='E')        {            scanf("%d%d",&x,&y);            if(ch[0] == 'A')            {                update(1,x,y);                //printf("A");            }            else if(ch[0] == 'S')            {               // printf("S");                update(1,x,-y);            }            else if(ch[0] == 'Q')            {                s=0;                //printf("Q");                query(1,x,y);                printf("%d\n",s);            }        }    }    return 0;}