敌兵布阵(线段树)

传送门:https://vjudge.net/contest/66989#problem/A

分析:求区间和,但是每个区间的值会有改变。因此想到了线段树。这是我写的第一到关于线段树的题。

线段树讲解 

我的ac代码:

#include <iostream>
#include <stdio.h>
#define maxn 50005
using namespace std;
int a[maxn],tree[maxn<<2];
void build(int p,int l,int r)
{
    if(l==r){scanf("%d",&tree[p]);return ;}
    int mid = (l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    tree[p]=tree[p*2]+tree[p*2+1];
}
void change(int p,int l,int r,int x,int num)//坐标:x,改变值:num;p,根节点
{
    if(l==r){tree[p]+=num;return ;}
    int mid=(l+r)/2;
    if(x<=mid)change(p*2,l,mid,x,num);
    else change(p*2+1,mid+1,r,x,num);
    tree[p]=tree[p*2]+tree[p*2+1];//一般修改这里;
}
int  find(int p,int l,int r,int x,int y)//l,r为树的区间端点
{
    if(x<=l&&r<=y)return tree[p];
    int mid = (l+r)/2;
    int ret =0;
    if(x<=mid)ret+=find(p*2,l,mid,x,y);
    if(y>mid)ret+=find(p*2+1,mid+1,r,x,y);
    return ret;
}
int main()
{
   int T;
   int l=0;
   int n;
   char s[10];
   cin>>T;
   while(T--)
   {
       printf("Case %d:\n",++l);
       scanf("%d",&n);
        build(1,1,n);
        int j,k;
       while(1)
       {
           scanf("%s",s);
           if(s[0]=='A')
           {
                scanf("%d%d",&j,&k);
               change(1,1,n,j,k);
           }
           else if(s[0]=='S')
           {
               scanf("%d%d",&j,&k);
               change(1,1,n,j,-k);
           }
           else if(s[0]=='Q')
           {
               scanf("%d%d",&j,&k);
               printf("%d\n",find(1,1,n,j,k));
           }
           else break;
       }
   }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/guagua_de_xiaohai/article/details/81194795