您的位置:首页 > 其它

线段树 HDU1166 敌兵布阵

2015-04-16 13:33 260 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16216

题意:给定每个点的人数,并且中间会有增减的操作。求某一段区间的人数和

思路:线段树第一题,所以多少有点参考别人代码。主要熟悉了下线段树的建立、查找、更新的方法,采用二进制。

源码:

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

int const MAXN = 50000+5;

int peo[MAXN<<2];

int n;

int query(int l,int r,int L,int R,int st)

{

int ans = 0;

if(l<=L && r>=R)

return peo[st];

int mid = (L+R)>>1;

if(mid>=l) ans+=query(l,r,L,mid,st<<1);

if(mid<r) ans+=query(l,r,mid+1,R,(st<<1)+1);

// printf("ans = %d\n",ans);

return ans;

}

void update(int mark,int add,int L,int R,int st)

{

if(L==R){

peo[st] += add;

return;

}

else{

int mid = (R+L)/2;

int ans = 0;

if(mid>=mark) update(mark,add,L,mid,st<<1);

else update(mark,add,mid+1,R,(st<<1)+1);

// printf("ans = %d\n",ans);

peo[st] = peo[st<<1] + peo[(st<<1)+1];

return;

}

// for(int i=1;i<=(n<<2); i++)

// printf("%d ",peo[i]);

// printf("\n");

}

int main()

{

int t;

scanf("%d",&t);

for(int i=1; i<=t; i++){

memset(peo,0,sizeof(peo));

int a,b;

char temp[5];

scanf("%d",&n);

for(int j=1; j<=n; j++){

scanf("%d",&b);

update(j,b,1,n,1);

}

printf("Case %d:\n",i);

while(scanf("%s",temp)!=EOF && temp[0]!='E'){

scanf("%d%d",&a,&b);

if(temp[0]=='Q')

printf("%d\n",query(a,b,1,n,1));

if(temp[0] == 'A') update(a,b,1,n,1);

else if(temp[0] == 'S') update(a,-b,1,n,1);

// for(i=1; i<(n<<2); i++)

// printf("%d ",peo[i]);

// printf("\n");

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: