HDU 1166 敌兵布阵

树状数组

#include <cstdio>
#include <cstring>
using namespace std;
const int N=50010;
int T,n,cnt=1,x,y;
char s[6];
int c[N];
void init(){for(int i=0;i<N;i++)c[i]=0;}
void add(int x,int num){while(x<=n)c[x]+=num,x+=x&-x;}
int sum(int x){int s=0;while(x>0)s+=c[x],x-=x&-x;return s;}
int main(){
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d",&n);
        for(int i=1;i<=n;i++){scanf("%d",&x);add(i,x);}
        printf("Case %d:\n",cnt++);
        while(scanf("%s",s),strcmp(s,"End")){  
            scanf("%d%d",&x,&y);  
            if(strcmp(s,"Add")==0)add(x,y);  
            else if(strcmp(s,"Sub")==0)add(x,-y);  
            else printf("%d\n",sum(y)-sum(x-1));         
        } 
    }
    return 0;
}

线段树

#include <cstdio> 
#include <cstring>
const int N=60000;
int T,n,cnt=1,x,y,sum[N<<2];
char s[6];
void init(){for(int i=1;i<N*4;i++)sum[i]=0;}
void up(int x){sum[x]=sum[x<<1]+sum[x<<1|1];}
void build(int l,int r,int x){
    if(l==r){scanf("%d",&sum[x]);return;}
    int mid=(l+r)>>1;
    build(l,mid,x<<1); build(mid+1,r,x<<1|1);
    up(x);//注意不要漏写
}
void update(int t,int num,int l,int r,int x){
    if(l==r){sum[x]+=num;return;}
    int mid=(l+r)>>1;
    if(t<=mid)update(t,num,l,mid,x<<1);
    else update(t,num,mid+1,r,x<<1|1);
    up(x);//同上
}
int query(int L,int R,int l,int r,int x){
    if(L<=l&&r<=R){return sum[x];}
    int mid=(l+r)>>1,tmp=0;
    if(L<=mid)tmp+=query(L,R,l,mid,x<<1);
    if(R>mid)tmp+=query(L,R,mid+1,r,x<<1|1);
    return tmp;
}
int main(){
    scanf("%d",&T);
    while(T--){
        init();
        printf("Case %d:\n",cnt++);
        scanf("%d",&n);
        build(1,n,1);
        while(scanf("%s",s),strcmp(s,"End")){  
            scanf("%d%d",&x,&y);  
            if(strcmp(s,"Add")==0)update(x,y,1,n,1);  
            else if(strcmp(s,"Sub")==0)update(x,-y,1,n,1);  
            else printf("%d\n",query(x,y,1,n,1));         
        }  
    }
    return 0;
}
posted @ 2014-02-25 19:26  forever97  阅读(221)  评论(0编辑  收藏  举报