线段树 (区间更新求和)

来源:互联网 发布:知乎suck for living 编辑:程序博客网 时间:2024/05/02 02:39
  1. #include <cstdio>  
  2. #define LL __int64  
  3.   
  4. const int N = 500010;  
  5. LL num[N], sum[N], add[N], v;  
  6.   
  7. void pushDown(int i, int l, int r) {  
  8.     if(add[i] != 0) {  
  9.         int mid = l + r >> 1;  
  10.         add[i << 1] += add[i];  
  11.         sum[i << 1] += (mid - l + 1) * add[i];  //[l, mid]代表左儿子区间  
  12.         add[i << 1 | 1] += add[i];  
  13.         sum[i << 1 | 1] += (r - mid) * add[i];  //[mid + 1, r]代表右儿子区间  
  14.         add[i] = 0;  
  15.     }  
  16. }  
  17.   
  18. void update(int i, int l, int r, int ql, int qr, int val) {  
  19.     if(l > qr || ql > r)  
  20.         return ;  
  21.     if(l >= ql && r <= qr){  
  22.         sum[i] += (r - l + 1) * val;  
  23.         add[i] += val;  
  24.         return ;  
  25.     }  
  26.     pushDown(i, l, r);  
  27.     int mid = l + r >> 1;  
  28.     update(i << 1, l, mid, ql, qr, val);  
  29.     update(i << 1 | 1, mid + 1, r, ql, qr, val);  
  30.     sum[i] = sum[i << 1] + sum[i << 1 | 1];  
  31. }  
  32.   
  33. LL query(int i, int l, int r, int ql, int qr) {  
  34.     if(l > qr || ql > r)  
  35.         return 0;  
  36.     if(l >= ql && r <= qr)  
  37.         return sum[i];  
  38.     pushDown(i, l, r);  
  39.     int mid = l + r >> 1;  
  40.     return query(i << 1, l, mid, ql, qr)   
  41.         + query(i << 1 | 1, mid + 1, r, ql, qr);  
  42. }  
  43.   
  44. int main() {  
  45.     int n, q, l, r;  
  46.     char ord;  
  47.     scanf("%d%d", &n, &q);  
  48.     for(int i = 1; i <= n; i++) {  
  49.         scanf("%lld", &num[i]);  
  50.         update(1, 1, n, i, i, num[i]);  
  51.     }  
  52.     while(q--) {  
  53.         scanf("\n%c", &ord);  
  54.         if(ord == 'Q') {  
  55.             scanf("%d%d", &l, &r);  
  56.             printf("%lld\n", query(1, 1, n, l, r));  
  57.         } else {  
  58.             scanf("%d%d%lld", &l, &r, &v);  
  59.             update(1, 1, n, l, r, v);  
  60.         }  
  61.     }  
  62.     return 0;  
  63. }  
0 0
原创粉丝点击