一道简单的线段树,可是对于脑残的我写起来也废了好大功夫~~QWQ
因为是区间更新所以需要添加一个down函数,
但是少了一个+号WA了好久~~qwq
注意写法~~
# include <cstdio>
# include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn=100000+10;
LL s[maxn<<2],a[maxn<<2];
int n;
void pushup(int rt)
{
s[rt]=s[rt<<1]+s[rt<<1|1];
}
void down(int l,int r,int rt)
{
if(a[rt]!=0)
{
int m=(l+r)>>1;
a[rt<<1]+=a[rt]; //忘了一个+号WA了好久qwq
a[rt<<1|1]+=a[rt];
s[rt<<1]+=(m-l+1)*a[rt];
s[rt<<1|1]+=(r-m)*a[rt];
a[rt]=0;
}
}
void build(int l,int r,int rt)
{
s[rt]=0;
a[rt]=0;
if(l==r)
return ;
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
a[rt]+=c;
s[rt]+=(r-l+1)*c;
return ;
}
down(l,r,rt);
int m=(l+r)>>1;
if(L<=m)
update(L,R,c,l,m,rt<<1);
if(R>m)
update(L,R,c,m+1,r,rt<<1|1);
pushup(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
LL ans=0;
if(L<=l&&R>=r)
{
return s[rt];
}
down(l,r,rt);
int m=(l+r)>>1;
if(L<=m)
ans+=query(L,R,l,m,rt<<1);
if(R>m)
ans+=query(L,R,m+1,r,rt<<1|1);
return ans;
}
int main()
{
int t,c,x,y,m;
char op[10];
scanf("%d%d",&n,&m);
build(1,n,1);
for(int i=1; i<=n; i++)
{
scanf("%d",&c);
update(i,i,c,1,n,1);
}
for(int i=0; i<m; i++)
{
scanf("%s",op);
if(op[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%I64d\n",query(x,y,1,n,1));
}
else
{
scanf("%d%d%d",&x,&y,&t);
update(x,y,t,1,n,1);
}
}
return 0;
}