线段树模板,先建树后,可实现查找,更新
#include <iostream>
#include <stdio.h>
using namespace std;
#define N 111111
long long sum[N<<2];//数组开的太大,要用宏定义,不然RE
long long add[N<<2];
void pushdown(int m,int rt)
{
if(add[rt])
{
add[rt*2]+=add[rt];
add[rt*2+1]+=add[rt];
sum[rt*2]+=add[rt]*(m-(m/2));
sum[rt*2+1]+=add[rt]*(m/2);
add[rt]=0;
}
}
void build(int l,int r,int rt)
{
add[rt]=0;
if(l==r)
{
scanf("%I64d",&sum[rt]);
return ;
}
int mid=(r+l)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
void update(int l,int r,int rt,int L,int R,int c)
{
if(l<=L && r>=R)
{
sum[rt]+=(long long)c*(R-L+1);
add[rt]+=c;
return ;
}
pushdown(R-L+1,rt);
int mid=(R+L)/2;
if(l<=mid) update(l,r,rt*2,L,mid,c);
if(r>mid) update(l,r,rt*2+1,mid+1,R,c);
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
long long query(int l,int r,int rt,int L,int R)
{
long long ans=0;
if(l<=L && r>=R) return sum[rt];
pushdown(R-L+1,rt);
int mid=(R+L)/2;
if(l<=mid) ans+=query(l,r,rt*2,L,mid);
if(r>mid) ans+=query(l,r,rt*2+1,mid+1,R);
return ans;
}
int main()
{
int n,m;scanf("%d%d",&n,&m);
build(1,n,1);
while(m--)
{
char ch[5];scanf(" %s",ch);
int c,x,y;
if(ch[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%I64d\n",query(x,y,1,1,n));
}
else
{
scanf("%d%d%d",&x,&y,&c);
update(x,y,1,1,n,c);
}
}
return 0;
}
/*
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
*/