1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <iostream> #include <cstdio> using namespace std;
const int N = 100010;
int n, m; int A[N]; char s[100];
typedef long long LL; struct node{ int L, R; LL tag, sum; int len(){ return (R-L+1);}
}tree[N<<2];
void up(int p){ tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum; }
void build(int L, int R, int p){ tree[p].L = L, tree[p].R =R; if(L==R){ tree[p].sum = A[L]; return ; } int mid = L+R>>1; build(L, mid, p<<1); build(mid+1, R, p<<1|1);
up(p); }
void down(int p){ LL &t = tree[p].tag; if(t==0) return; tree[p<<1].tag += t; tree[p<<1].sum += t * tree[p<<1].len();
tree[p<<1|1].tag += t; tree[p<<1|1].sum += t*tree[p<<1|1].len();
t = 0; }
void update(int L, int R, int x, int p){ if(tree[p].L ==L && tree[p].R ==R){ tree[p].tag += x; tree[p].sum += tree[p].len() * x; return ; } down(p); int mid = tree[p].L + tree[p].R >>1; if(R<=mid) update(L, R, x, p<<1); else if(L>mid) update(L, R, x, p<<1|1); else { update(L, mid, x, p<<1); update(mid+1, R, x, p<<1|1); } up(p); }
LL query(int L, int R, int p){ if(tree[p].L==L && tree[p].R==R){ return tree[p].sum; }
down(p); int mid = tree[p].L + tree[p].R >>1; if(R<=mid) return query(L, R, p<<1); else if(L>mid) return query(L, R, p<<1|1); else { return query(L, mid, p<<1) + query(mid+1, R, p<<1|1); } }
int main(){ scanf("%d%d", &n, &m); for(int i=1;i<=n;i++) scanf("%d", &A[i]); build(1, n, 1); while(m--){ scanf("%s", s); if(s[0]=='A'){ int a, b, c; scanf("%d%d%d", &a, &b, &c); update(a, b, c, 1); }else{ int a, b; scanf("%d%d", &a, &b); printf("%lld\n", query(a, b, 1)); }
} return 0; }
|