#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <vector> using namespace std; const int maxn = 101000; //3468 Accepted 4872K 3172MS C++ 2204B 2013-08-09 20:35:27 //这道题目WA了好多次,在discuss里面看到一句话“一气之下把所有变量改为__int64”就ac啦。 __int64 sumv[maxn*3]; __int64 addv[maxn*3];// 保存每个节点整个区间要加上的值。 __int64 N, Q; __int64 ql, qr; __int64 _sum = 0;//全局变量,保存每次查询的解。 void maintain(__int64 o, __int64 L, __int64 R) { __int64 lc = o*2, rc = o*2 + 1; if(L < R) {//如果有左右孩子 sumv[o] = sumv[lc] + sumv[rc]; } sumv[o] += (R-L+1) * addv[o];//如果R-L != 0 则add[o]回影响其子孙节点. if(L == R) addv[o] = 0; } void update(__int64 o, __int64 L, __int64 R, __int64 v) { //v 是要更新的值。 if(ql <= L && R <= qr) { addv[o] += v; //开始初始化add[o] = 0; } else { __int64 lc = o*2, rc = o*2 + 1; __int64 M = L + (R-L)/2; if(ql <= M) update(lc, L, M, v); if(qr > M) update(rc, M+1, R, v); } maintain(o, L, R); } void query(__int64 o, __int64 L, __int64 R, __int64 add) { if(ql <= L && R <= qr) { _sum += sumv[o] + add*(R-L+1); } else { __int64 M = (L+R)/2; if(ql <= M) query(o*2, L, M, add+addv[o]); if(qr > M) query(o*2+1, M+1, R, add+addv[o]); } } void init() { _sum = 0;//!!!! for(int i = 0; i < N*3; i++) { addv[i] = 0; sumv[i] = 0; } } int main() { __int64 temp; char s[5]; __int64 from, to; __int64 value; while(scanf("%I64d%I64d", &N, &Q) != EOF) { init(); for(int i = 1; i <= N; i++) { scanf("%I64d", &temp); ql = qr = i; update(1, 1, N, temp); } for(int i = 1; i <= Q; i++) { scanf("%s", s); getchar(); if(s[0]=='Q') { scanf("%I64d%I64d", &from, &to); ql = from; qr = to; query(1, 1, N, 0); printf("%I64d\n", _sum); _sum = 0; } if(s[0]=='C') { scanf("%I64d%I64d%I64d", &from, &to, &value); ql = from; qr = to; update(1, 1, N, value); } } } return 0; }