【HDOJ】1166 敌兵布阵 (线段树)

来源:互联网 发布:网络诈骗方法揭秘 编辑:程序博客网 时间:2024/05/21 05:08

【Problem】http://acm.hdu.edu.cn/showproblem.php?pid=1166

        给定一个数组a[]和一系列的操作,应答每个询问。

        操作:Add i x:a[i]+=x  Sub i x:a[i]-=x  Query l r:询问Σ(a[l..r])

【Analysis

        对于Sub i x操作,完全可以用Add i -x来代替。

        标准的线段树,比较简单类型的。具体的可以去看wiki。

【Code】

// Task: 1166#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>using namespace std;#define nil NULLclass SegmentTree{    public:        int x;    // 节点值        int l,r;  // 区间左右标记        SegmentTree*left,*right;  // 左右子树        SegmentTree (int L=0,int R=0)        {            l=L,r=R;            x=0;            left=right=nil;        }}*root;SegmentTree*Build(int a[],int L,int R){    if (L>R) return nil;    else    {        SegmentTree*ret=new SegmentTree(L,R);        if (L==R)            ret->x=a[L];        else        {            int K=(L+R)>>1;            if ((ret->left=Build(a,L,K))!=nil) ret->x+=ret->left->x;            if ((ret->right=Build(a,K+1,R))!=nil) ret->x+=ret->right->x;        }      //  cout << L << " " << R << " " << ret->x << endl;        return ret;    }}void Add(int i,int x){    SegmentTree*p=root;    while (p!=nil)    {        p->x+=x;        int k=(p->l+p->r)>>1;        if (i<=k) p=p->left;        else p=p->right;    }}int Query(int l,int r,SegmentTree*p=root){    if (p==nil||l>r) return 0;    else    {        int ret=0;        if (p->l==l&&p->r==r) return p->x;   // 完美包含        int k=(p->l+p->r)>>1;        if (r<=k) return Query(l,r,p->left);  // 全都在左子树        if (l>k) return Query(l,r,p->right);  // 全都在右子树        if (l<=k) ret+=Query(l,k,p->left);    // 交叉包含左子树部分        if (r>k) ret+=Query(k+1,r,p->right);  // 交叉包含右子树部分    //    printf("%d(%d)-%d(%d) %d\n",l,p->l,r,p->r,ret);        return ret;    }}const int N = 50000;int n;int a[N+1];char cmd[10];int main(){    int T;    scanf("%d",&T);    for (int dex=1;dex<=T;dex++)    {        printf("Case %d:\n",dex);        scanf("%d",&n);        for (int i=1;i<=n;i++)            scanf("%d",a+i);        root=Build(a,1,n);        scanf("%s",cmd);        while (cmd[0]!='E')        {            int l,r;            scanf("%d%d",&l,&r);            switch(cmd[0])            {                case 'A':Add(l,r);break;                case 'S':Add(l,-r);break;                case 'Q':printf("%d\n",Query(l,r));break;            }            scanf("%s",cmd);        }    }    return 0;}


 

原创粉丝点击