模板:树状数组(带区间修改和区间更新)
转自:http://blog.csdn.net/qq_21841245/article/details/43956633
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define N 200010 6 typedef long long LL; 7 8 LL bit[2][N], sum[N], a[N], maxn; 9 // bit[0]维护delta[x]. bit[1]维护delta[x]*x 10 // sum[i] = a[1]+...+a[i] + delta[1]*i + delta[2]*(i - 1) + delta[3]*(i - 2)+...+delta[i]*1 // a[i]为原始数组 11 // = sigma( a[x] ) + sigma( delta[x] * (i + 1 - x) ) 12 // = sigma( a[x] ) + (i + 1) * sigma( delta[x] ) - sigma( delta[x] * x ) 13 int lowbit(int x) { return x & (-x); } 14 void update(int i, int x, int w) { while(x <= maxn) bit[i][x] += w, x += lowbit(x); } 15 LL query(int i, int x) { LL ans = 0; while(x) ans += bit[i][x], x -= lowbit(x); return ans; } 16 void Add(int l, int r, int w) { 17 update(0, l, w); update(0, r + 1, -w); 18 update(1, l, w * l); update(1, r + 1, -w * (r + 1)); 19 } 20 LL Sum(int l, int r) { 21 LL suml = sum[l - 1] + l * query(0, l - 1) - query(1, l - 1); 22 LL sumr = sum[r] + (r + 1) * query(0, r) - query(1, r); 23 // printf("sum : %d, %d\n", suml, sumr); 24 return sumr - suml; 25 } 26 27 int main() { 28 int n, q; 29 scanf("%d", &n); 30 for(int i = 1; i <= n; i++) scanf("%d", &a[i]), sum[i] = sum[i-1] + a[i], Add(i, i, a[i]); 31 scanf("%d", &q); maxn = n; 32 memset(bit, 0, sizeof(bit)); 33 while(q--) { 34 int a, b, c, d; 35 scanf("%d", &a); 36 if(a == 1) { 37 scanf("%d%d%d", &b, &c, &d); 38 Add(b, c, d); 39 } else { 40 scanf("%d%d", &b, &c); 41 printf("%lld\n", Sum(b, c)); 42 } 43 } 44 return 0; 45 }