/* * POJ_3468.cpp * * Created on: 2013年11月25日 * Author: Administrator */ #include <iostream> #include <cstdio> #define maxn 100010 #define Fup(i, s, t) for (int i = s; i <= t; i ++) #define Fdn(i, s, t) for (int i = s; i >= t; i --) using namespace std; struct node {//线段树 long long mark;//节点i的懒惰标记为tree[i].mark long long sum;//节点i的数和为tree[i].sum } tree[maxn * 4]; int x[maxn];//初始值序列 int n;//数字个数 int m;//操作次数 void update(int l, int r, int i) {//标记法维护线段树(根为i,对应区间[l,r]) if (!tree[i].mark) return; int mid = (l + r) / 2; tree[i + i].sum += tree[i].mark * (long long) (mid - l + 1); tree[i + i + 1].sum += tree[i].mark * (long long) (r - mid); tree[i + i].mark += tree[i].mark; tree[i + i + 1].mark += tree[i].mark; tree[i].mark = 0; } long long query(int tl, int tr, int l, int r, int i) {//计算线段树的数字和(根为i,对应区间[l,r]内子区间[tl,tr]的数字和) if (tl > r || tr < l) return 0; if (tl <= l && r <= tr) return tree[i].sum; update(l, r, i); int mid = (l + r) / 2; return query(tl, tr, l, mid, i + i) + query(tl, tr, mid + 1, r, i + i + 1); } //线段树中区间[l,r]的子区间[tl,tr]中的每个数+val void add_value(int tl, int tr, int l, int r, int i, int val) { if (tl > r || tr < l) return; if (tl <= l && r <= tr) { tree[i].sum += val * (long long) (r - l + 1); tree[i].mark += val; return; } update(l, r, i); int mid = (l + r) / 2; add_value(tl, tr, l, mid, i + i, val); add_value(tl, tr, mid + 1, r, i + i + 1, val); tree[i].sum = tree[i + i].sum + tree[i + i + 1].sum; } //建立根为i,对应区间[1..n]的线段树 void build_tree(int l, int r, int i) { if (l == r) { tree[i].sum = x[l]; return; } int mid = (l + r) / 2; build_tree(l, mid, i + i); build_tree(mid + 1, r, i + i + 1); tree[i].sum = tree[i + i].sum + tree[i + i + 1].sum; } void solve(){ build_tree(1,n,1);//****别漏了,记得要先建线段数 char ch; int i; // scanf("\n"); for(i = 1 ; i <= m ; ++i){ int l,r,v; scanf(" %c",&ch); if(ch == 'Q'){ scanf("%d%d",&l,&r); long long ans = query(l,r,1,n,1); printf("%lld\n",ans); // cout<<ans<<endl; }else if(ch == 'C'){ scanf("%d%d%d",&l,&r,&v); add_value(l,r,1,n,1,v); } } } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ int i; for(i = 1 ; i <= n ; ++i){ scanf("%d",&x[i]); } solve(); } return 0; }