HDU1166 敌兵布阵 线段树 模板题

题目链接

线段树模板之单点修改,区间查询

用线段树维护区间和.

树状数组也可以解决.会在后面补上.

注意:数据范围较大不要使用cin/cout

//线段树
#include
#include
#include
#include
using namespace std;
#define Mx 500020
#define inf 0x3f3f3f3f
struct node
{
    int l,r,key;
}q[Mx*2];
int a[Mx],root,ql,qr,tot,ans;
void update(int x)
{
    q[x].key=q[q[x].l].key+q[q[x].r].key;
}
int build(int s,int t)
{
    int now,mid;
    tot++;
    now=tot;
    if (s==t)
    {
        q[now].key=a[s];
        return now;
    }
    mid=(s+t)/2;
    q[now].l=build(s,mid);
    q[now].r=build(mid+1,t);
    update(now);
    return now;
}
void query(int x,int s,int t)
{
    if ((ql<=s)&&(qr>=t))
    {
        ans+=q[x].key;
        return;
    }
    int mid=(s+t)/2;
    if (ql<=mid) query(q[x].l,s,mid);
    if (qr>mid) query(q[x].r,mid+1,t);
}
void revise(int x,int s,int t)
{
    if ((ql==s)&&(s==t))
    {
        q[x].key+=qr;
        return;
    }
    int mid=(s+t)/2;
    if (ql<=mid) revise(q[x].l,s,mid);
        else revise(q[x].r,mid+1,t);
    update(x);
}
int main()
{
    int n,m,T;
    scanf("%d",&T);
    for (int Case=1;Case<=T;Case++)
    {
        printf("Case %d:\n",Case);
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        char s[10];
        tot=0;
        root=build(1,n);
        while (scanf("%s",s)&&s[0]!='E')
        {
            scanf("%d %d",&ql,&qr);
            if (!strcmp(s,"Query"))
            {
                ans=0;
                query(root,1,n);
                printf("%d\n",ans);
            }else if (!strcmp(s,"Add")) revise(root,1,n);
            else if (!strcmp(s,"Sub")) qr=-qr,revise(root,1,n);
        }
    }
    return 0;
}

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