hdu 1166 敌兵布阵

线段树最简单的题目:区间求和,修改单点数值,中文题目就不说题意了

今天看了神牛的代码感慨良多,写代码像写诗一样

感觉自己的代码就是写得太累赘

下次线段树要加大难度了

#include <cstdio>
#include <cstring>
#define N 50010
struct node
{
    int a,b;
    int sum;
}tree[4*N];
int n;

void updata(int p ,int e , int root)
{
    tree[root].sum+=e;
    if(tree[root].a==tree[root].b)
        return ;
    int mid=(tree[root].a+tree[root].b)/2;
    if(p<=mid)
        updata(p,e,2*root);
    else
        updata(p,e,2*root+1);
    return ;
}

int query(int a ,int b ,int root)
{
    int mid=(tree[root].a+tree[root].b)/2;
    if(tree[root].a==a && tree[root].b==b)
        return tree[root].sum;
    else if(a>mid)
        return query(a,b,2*root+1);
    else if(b<=mid)
        return query(a,b,2*root);
    else
        return query(a,mid,2*root)+query(mid+1,b,2*root+1);
}

void build(int a ,int b,int root)
{
    tree[root].a=a; tree[root].b=b;
    if(a==b)
    {
        scanf("%d",&tree[root].sum);
        return ;
    }
    int mid=(a+b)/2;
    build(a,mid,2*root);
    build(mid+1,b,2*root+1);
    tree[root].sum=tree[2*root].sum+tree[2*root+1].sum;
    return ;

}

int main()
{
    int T,Case;
    scanf("%d",&T);
    for(Case=1; Case<=T; Case++)
    {
      scanf("%d",&n);
      build(1,n,1);
      printf("Case %d:\n",Case);
      char s[10];
      while(1)
      {
          int a,b,ans;
          scanf("%s",s);
          if(s[0]=='E') break;
          scanf("%d%d",&a,&b);
          if(s[0]=='Q')
          {
              ans=query(a,b,1);  //询问区间[a,b]内的和
              printf("%d\n",ans);
          }
          else if(s[0]=='A')
            updata(a,b,1);  //元结点a的值增加b
          else
            updata(a,-b,1);  //元结点a的值减少b
      }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/scau20110726/p/2883817.html