简单的线段树,由于我对lazy标记还是不熟,花了点时间。。。。像这种题目,query和updata都要加上pushdown并更新父节点。注意结果会爆int。。
#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <climits>
#define maxn 400005
#define eps 1e-6
#define mod 1000000007
#define INF 99999999
#define lowbit(x) (x&(-x))
typedef long long LL;
using namespace std;
LL num[maxn];
LL mark[maxn];
LL segtree[maxn];
LL ql, qr, k;
LL n, m, ans;
char s[10];
void build(LL o, LL L, LL R)
{
mark[o]=0;
if(L==R){
segtree[o]=num[L];
return;
}
int mid=(L+R)>>1;
build(o<<1, L, mid);
build(o<<1 | 1, mid+1, R);
segtree[o]=segtree[o<<1]+segtree[o<<1 | 1];
}
void pushdown(LL o, LL L, LL R)
{
if(!mark[o]) return;
int mid=(L+R)>>1;
segtree[o<<1]+=(mid-L+1)*mark[o];
segtree[o<<1 | 1]+=(R-mid)*mark[o];
mark[o<<1]+=mark[o];
mark[o<<1 | 1]+=mark[o];
mark[o]=0;
}
void query(LL o, LL L, LL R)
{
if(ql<=L && qr>=R){
ans+=segtree[o];
return;
}
pushdown(o, L, R);
int mid=(R+L)>>1;
if(ql<=mid) query(o<<1, L, mid);
if(qr>mid) query(o<<1 | 1, mid+1, R);
segtree[o]=segtree[o<<1]+segtree[o<<1 | 1];
}
void updata(LL o, LL L, LL R)
{
if(ql<=L && qr>=R){
mark[o]+=k;
segtree[o]+=k*(R-L+1);
return;
}
pushdown(o, L, R);
int mid=(R+L)>>1;
if(ql<=mid) updata(o<<1, L, mid);
if(qr>mid) updata(o<<1 | 1, mid+1, R);
segtree[o]=segtree[o<<1]+segtree[o<<1 | 1];
}
void solve(void)
{
while(m--){
scanf("%s",s);
if(s[0]=='Q'){
scanf("%lld%lld",&ql,&qr);
ans=0;
query(1, 1, n);
printf("%lld\n", ans);
}
else{
scanf("%lld%lld%lld",&ql,&qr,&k);
updata(1, 1, n);
}
}
}
int main(void)
{
while(scanf("%lld%lld",&n,&m)!=EOF){
for(int i=1;i<=n;i++) scanf("%lld",&num[i]);
build(1, 1, n);
solve();
}
return 0;
}