点点滴滴”

导航

线段数Hdu1166

///线段数:区间更新 求和

 #include<iostream> #include<stdio.h> 
#include<string.h>

using namespace std;
#define N 50006 struct data
{
int l; int r; int sum; ///节点附加信息 此题为求和。。。
} node[N<<2]; int num[N],s; void build(int l,int r,int rt) { node[rt].l=l; node[rt].r=r; if(l==r) ///如果左右端点重合 { node[rt].sum=num[l]; ///和为左端点值 } else ///如果不重合 建树
{ int mid=(l+r)>>1; ///建立线段数 build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); node[rt].sum=node[rt<<1].sum+node[rt<<1|1].sum; ///rt:区间序号 等于左儿子及右儿子的值和 } } void update(int l,int r,int rt,int x,int val) ///x==a val===b cin>>a>>b(把b加到a上) rt 所在节点位置 { if(l==r) { node[rt].sum+=val; ///左右端点重合 该节点加b return; } int mid=(l+r)>>1; if(x<=mid) ///接下是递归 { update(l,mid,rt<<1,x,val); } if(x>mid) { update(mid+1,r,rt<<1|1,x,val); } node[rt].sum=node[rt<<1].sum+node[rt<<1|1].sum; /// } void search(int l,int r,int rt) { if(node[rt].l==l&&node[rt].r==r) { cout<<node[rt].sum<<endl; s+=node[rt].sum; return; } if(node[rt].l==node[rt].r) { //cout<<node[u].sum<<endl; s+=node[rt].sum; return; } if(r<=node[rt<<1].r) { search(l,r,rt<<1); } else if(l>=node[rt<<1|1].l) { search(l,r,rt<<1|1); } else { search(l,node[rt<<1].r,rt<<1); search(node[rt<<1|1].l,r,rt<<1|1); } } int main() { char ch[6]; int t,n,i,a,b,temp; while(scanf("%d",&t)) { temp=0; while(t--) { scanf("%d",&n); temp++; for(i=1; i<=n; i++) { scanf("%d",&num[i]); } printf("Case %d:\n",temp); build(1,n,1); //for(i=1;i<26;i++) //{ // cout<<node[i].left<<" "<<node[i].right<<" "<<node[i].sum<<endl; //} while(cin>>ch) { s=0; if(strcmp(ch,"End")==0) break; if(strcmp(ch,"Query")==0) { scanf("%d%d",&a,&b); search(a,b,1); printf("%d\n",s); } if(strcmp(ch,"Add")==0) { scanf("%d%d",&a,&b); update(1,n,1,a,b); } if(strcmp(ch,"Sub")==0) { scanf("%d%d",&a,&b); b=-b; update(1,n,1,a,b); } } } } return 0; }

 

 

posted on 2014-03-18 20:40  点点滴滴”  阅读(80)  评论(0编辑  收藏  举报