hdu1166线段树模板求和

来源:互联网 发布:高程测量软件 编辑:程序博客网 时间:2024/06/05 19:05

线段树模板,就不写其他的了

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node {int l,r,sum; }tr[200005];int a[50001];int i,j,k,m,n,t,x,y; int sum1;void build(int L,int R,int num) {tr[num].l=L;  tr[num].r=R;  if(L==R)tr[num].sum=a[L];  //已到单点,赋值;   else   {build(L,(L+R)/2,2*num);  //此处是向下向内部递归,注意头尾标号;     build((L+R)/2+1,R,2*num+1);    tr[num].sum=tr[num*2+1].sum+tr[num*2].sum;  //注意,大区间(非单点)的值一定要在递归回来之后赋值,否则小区间或单点的值为零;    }  }     void add(int x,int y,int num)  { tr[num].sum+=y; //所有包含点x的大区间都要变化,此处从上往下传递变化;    if(tr[num].l==tr[num].r)return ;   if(x>(tr[num].l+tr[num].r)/2)add(x,y,num*2+1);    if(x<=(tr[num].l+tr[num].r)/2)add(x,y,num*2);}  void query(int L,int R,int num) {if(tr[num].l>=L && tr[num].r<=R)     {sum1+=tr[num].sum;      return ;      }  int mid=(tr[num].l+tr[num].r)/2;  if(mid<L)query(L,R,num*2+1);   //要找的线段在当前线段右半部;    else if(mid>=R)query(L,R,num*2);  //要找的线段在当前线段左半部;else       //要找的线段一部分在左,一部分在右,两边都找;   {query(L,R,num*2+1);   query(L,R,num*2);   }  }int main() {scanf("%d",&t);  k=t;  while(t--)   {scanf("%d",&n);    printf("Case %d:\n",k-t);   for(i=1;i<=n;i++)scanf("%d",&a[i]);    build(1,n,1);    char str[5];while(~scanf("%s",&str))  {if(str[0]=='E')break;   scanf("%d%d",&x,&y);   sum1=0;   if(str[0]=='A')add(x,y,1);   if(str[0]=='S')add(x,-y,1);   if(str[0]=='Q')     {query(x,y,1);      printf("%d\n",sum1);  }       }   } return 0;  } 


0 0
原创粉丝点击