HDU1166 敌兵布阵(线段树)

HDU1166  敌兵布阵(线段树)

本题是线段树的基本模板题,包含以下几部分:

1、修改值

2、查询区间和

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int sum[maxn*4],add[maxn*4];
int a[maxn];
void pushup(int root)  //根节点的和=两个子节点的和
{
    sum[root]=(sum[root*2]+sum[root*2+1]);
}
void build(int l,int r,int root)//建树
{
    if(l==r)
  {
      sum[root] = a[l];
     return;
 }
    int mid=(l+r)/2;
    build(l,mid,root*2);
    build(mid+1,r,root*2+1);
    pushup(root);
}
void Add(int num,int val,int l,int r,int root)//修改值
{
    if(l==r&&num==l)
    {
        a[num]+=val;
        sum[root]=a[num];
        return;
    }
    int mid=(l+r)/2;
    if(num<=mid)
        Add(num,val,l,mid,root*2);
    else
        Add(num,val,mid+1,r,root*2+1);
    pushup(root);
}
int Query(int be,int ed,int l,int r,int root)//查询区间和
{
    if(be<=l&&r<=ed)
        return sum[root];
    int mid=(l+r)/2;
    int ans=0;
    if(be<=mid)
        ans+=Query(be,ed,l,mid,root*2);
    if(mid<ed)
        ans+=Query(be,ed,mid+1,r,root*2+1);
    return ans;
}

int main() {
    int T;
    scanf("%d",&T);
    int res=1;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&a[i]);
        }
        build(1,n,1);
        char s[10];
        int a,b;
        printf("Case %d:
",res);
        while(scanf("%s",s))
        {
            if(s[0]=='E')
                break;
            if(s[0]=='A')
            {
                scanf("%d %d",&a,&b);
                Add(a,b,1,n,1);
            }
            if(s[0]=='Q')
            {
                scanf("%d %d",&a,&b);
                printf("%d
",Query(a,b,1,n,1));

            }
            if(s[0]=='S')  //减去某个值可以认为是加上某值的相反数
            {
                scanf("%d %d",&a,&b);
                Add(a,-b,1,n,1);
            }
        }
        res++;
    }

    return 0;
}
原文地址:https://www.cnblogs.com/acmer-hmin/p/11813017.html