您的位置:首页 > 其它

hdu1166简单线段树

2013-08-18 11:24 369 查看
题意是初始化炮兵人数,然后对其进行一系列修改,最后查询区间人数和

 用一般数组做会超时,改用线段树

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

int num[50050];

class tree

{public:

    int l,r,data;                                //data存每棵树区间内的人数

}tree[150050];

 void insert(int n,int l,int r)           //n表示第n个数,从1开始不停地初始化树
{tree
.l=l;                                   
//初始化每棵树代表的左右区间
tree
.r=r;

        if(l==r)

        tree
.data=num[l];             //num数组存各个兵营的人数
        else

        {

            int mid=(l+r)>>1;             //递归继续初始化左右子树
            insert(2*n,l,mid);

            insert(2*n+1,mid+1,r);

            tree
.data=tree[2*n].data+tree[2*n+1].data;

        }

    }

void modify(int n,int x,int temp)

{if(tree
.l==tree
.r)               //修改时,从第一棵树传进来往下搜,然后从下往上维护data

    {

        tree
.data+=temp;

        return ;

    }

        int mid;

        mid=(tree
.l+tree
.r)/2;

        if(x<=mid)                        //x表示第几个兵营,因此用X来和mid做比较从而选择在左子树还是右子树
        modify(n*2,x,temp);

        else

        modify(n*2+1,x,temp);

         tree
.data+=temp;

}

int query(int n,int a,int b)

{if(tree
.l==a&&tree
.r==b)//查询同修改类似,先自上而下,然后从下往上返回data值
return tree
.data;

else

{

    int mid=(tree
.l+tree
.r)/2; //选择所查询区间在左子树还是右子树,或者是由左右子树部分区间之和
    if(a>mid)

    return query(n*2+1,a,b);

    else

    {

        if(b<=mid)

        return query(n*2,a,b);

        else

        return query(n*2,a,mid)+query(n*2+1,mid+1,b);

    }

}

}

int main()

{int t,key=1;

//freopen("E:\\in.txt","r",stdin);

scanf("%d",&t);

while(t--)

{printf("Case %d:\n",key++);

    memset(num,0,sizeof(num));

    int n;

    scanf("%d",&n);

    for(int i=1;i<=n;i++)

   scanf("%d",&num[i]);

    insert(1,1,n);

    //char str[6];

    string str;

    int a,b;

    while(cin>>str)

    {if(str=="End")

    break;

          scanf("%d%d",&a,&b);

    if(str=="Add")

    {

    modify(1,a,b);

    }

        if(str=="Sub")

        {

        modify(1,a,-1*b);

        }

        if(str=="Query")

        {

            printf("%d\n",query(1,a,b));

        }

    }

}

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线段树 hdu1166