简单的线段树,由于我对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;
}