题干略,线段树裸题,不带懒惰标记的.
好久没看线段树发现懒惰标记不大会了补几篇博客备自查,直接贴的自己以前板子题的代码.
如果要用class写函数不能写在里面,不然this指针不好递归,或者静态也许也星.
root<<1为左儿子,root<<1|1为右儿子,pushup是向上更新值.
left和right是闭区间.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50005;
#define INF 0x3f3f3f3f
int value[maxn*4];
void pushUP(int root)
{
value[root] = value[root<<1]+value[root<<1|1];
}
void build(int root,int left,int right)
{
if(left == right)
{
scanf("%d",&value[root]);
return;
}
int mid = (left+right)/2;
build(root<<1, left,mid);
build(root<<1|1,mid+1,right);
pushUP(root);
}
int query(int root,int left,int right,int root_left,int root_right)
{
//找到了
if(root_left == left && root_right == right)
return value[root];
//如果不在里面
int ans = 0;
int mid = (root_left+root_right)/2;
if(right<=mid)
ans+=query(root<<1,left,right,root_left,mid);
else if(left>mid)
ans+=query(root<<1|1,left,right,mid+1,root_right);
else
{
ans += query(root<<1,left,mid,root_left,mid);
ans += query(root<<1|1,mid+1,right,mid+1,root_right);
}
return ans;
}
void update(int root,int pos,int val,int left,int right)
{
if(left == right)
{
value[root] += val;
return;
}
int mid = (left+right)>>1;
if(pos <= mid)
update(root<<1,pos,val,left,mid);
else
update(root<<1|1,pos,val,mid+1,right);
pushUP(root);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1; i<=t; i++)
{
printf("Case %d:\n",i);
int n;
scanf("%d",&n);
build(1,1,n);//根节点,长度
char a[10];
int b,c;
while(scanf("%s",a)!=EOF)
{
if(a[0] == 'E')break;
scanf("%d%d",&b,&c);
if(a[0] == 'Q')
cout<<query(1,b,c,1,n)<<endl;
else if(a[0] == 'A')
update(1,b,c,1,n);
else if(a[0] == 'S')
update(1,b,-c,1,n);
}
}
}