hdu 1166敌兵布政(线段树)

裸题,不解释
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 50010 using namespace std; int n,t; char s[10]; struct node{ int l,r,sum;//维护一个左标记,右标记,还有一个区间和 }xd[4*maxn+5]; void build(int l,int r,int p) { xd[p].l=l; xd[p].r=r; if(l==r) {scanf("%d",&xd[p].sum);return;} build(l,(l+r)/2,p*2); build((l+r)/2+1,r,p*2+1); xd[p].sum=xd[p*2].sum+xd[p*2+1].sum; } void modi(int md,int d,int p)//实现单点修改 { if(xd[p].l==md&&xd[p].r==md) {xd[p].sum+=d;return;} if(xd[p].l<=md&&md<=xd[p].r) { modi(md,d,p<<1); modi(md,d,(p<<1)+1); xd[p].sum=xd[p].sum+d; return; } } //查询函数的问题 l和r表示要查询的区间 int query(int l,int r,int p) { if(l>xd[p].r||r<xd[p].l) return 0;//完全相离的情况 if(l<=xd[p].l&&r>=xd[p].r) return xd[p].sum;//区间包含p点 int ans1=query(l,r,p*2); int ans2=query(l,r,p*2+1); //int ans1=query(l,xd[p*2].r,p*2); //这种写法就是错误的,区间应该是不变的,这样就人为的扩大了区域 //如果区间有交集,这种写法是对的,如果p点完全包含区间就会人为的扩大区域 //int ans2=query(xd[p*2+1].l,r,p*2+1); return ans1+ans2; } int main() { scanf("%d",&t); int ans=0,m=0,b=0,k=1; while(k<=t) { memset(xd,0,sizeof(xd)); printf("Case %d:\n",k); scanf("%d",&n); build(1,n,1); int a,b,m; while(scanf("%s",s)&&s[0]!='E') { if(s[0]=='Q') { scanf("%d%d",&m,&b); ans=query(m,b,1); printf("%d\n",ans); } if(s[0]=='A') { scanf("%d%d",&m,&b); modi(m,b,1); } if(s[0]=='S') { scanf("%d%d",&m,&b); modi(m,-b,1); } } k++; } }

 

posted @ 2017-06-27 23:04  xinyimama  阅读(81)  评论(0)    收藏  举报