单点更新区间求和 hdu1166 地兵布阵

 hdu1166 地兵布阵

         题目大意: 有N个工兵营,每个工兵营开始有a个人,然后有一些操作。Add i j 第i个工兵营加j个人 Sub 第i个工兵营减j个人,Q i j 询问第i到第j个工兵营的总人数。

         解题思路:O(-1)

#include 
#include 
using namespace std;

#define lz 2*u,l,mid
#define rz 2*u+1,mid+1,r
const int maxn=55555;
int sum[2*maxn], a[maxn];

void build(int u, int l, int r)
{
    sum[u]=0;
    if(l==r)
    {
        sum[u]=a[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lz);
    build(rz);
    sum[u]=sum[2*u]+sum[2*u+1];
}

void Update(int u, int l, int r, int pos, int c)
{
    if(l==r)
    {
        sum[u]+=c;
        return ;
    }
    int mid=(l+r)>>1;
    if(pos<=mid) Update(lz,pos,c);
    else Update(rz,pos,c);
    sum[u]=sum[2*u]+sum[2*u+1];
}

int Query(int u, int l, int r, int tl, int tr)
{
    if(tl<=l&&r<=tr) return sum[u];
    int mid=(l+r)>>1;
    if(tr<=mid) return Query(lz,tl,tr);
    else if(tl>mid) return Query(rz,tl,tr);
    else
    {
        int t1=Query(lz,tl,mid);
        int t2=Query(rz,mid+1,tr);
        return t1+t2;
    }
}

int main()
{
    int n, T, tcase=0;
    cin >> T;
    while(T--)
    {
        printf("Case %d:\n",++tcase);
        cin >> n;
        for(int i=1; i<=n; i++)
            scanf("%d",a+i);
        build(1,1,n);
        char op[10];;
        while(scanf("%s",op))
        {
            if(op[0]=='E') break;
            else
            {
                int l, r;
                scanf("%d%d",&l,&r);
                if(op[0]=='Q') printf("%d\n",Query(1,1,n,l,r));
                else
                {
                    if(op[0]=='S') r*=-1;
                    Update(1,1,n,l,r);
                }
            }
        }
    }
    return 0;
}


你可能感兴趣的:(线段树)