hdu1166线段树模板求和

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

#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值