您的位置:首页 > 其它

树状数组模板(改点求段 / 该段求点 / 改段求段)

2017-07-25 22:10 274 查看
1. 改点求段(单点更新, 区间求和)

代码:

1 #include <iostream>
2 #include <stdio.h>
3 #define ll long long
4 using namespace std;
5
6 const int MAXN = 2e5 + 10;
7 ll a[MAXN], d[MAXN], c[MAXN];//d[i]=a[i]-a[i-1], c[i]=(i-1)*d[i]
8 int n;
9
10 int lowbit(int x){
11     return x & -x;
12 }
13
14 void add(ll *tree, int x, ll ad){
15     while(x <= n){
16         tree[x] += ad;
17         x += lowbit(x);
18     }
19 }
20
21 ll sum(ll *tree, int x){
22     ll ans = 0;
23     while(x > 0){
24         ans += tree[x];
25         x -= lowbit(x);
26     }
27     return ans;
28 }
29
30 int main(void){
31     ll ad;
32     int q, op, l, r;
33     scanf("%d", &n);
34     for(int i = 1; i <= n; i++){
35         scanf("%lld", &a[i]);
36         add(d, i, a[i] - a[i - 1]);
37         add(c, i, (i - 1) * (a[i] - a[i - 1]));
38     }
39     scanf("%d", &q);
40     while(q--){
41         scanf("%d", &op);
42         if(op == 1){
43             scanf("%d%d%lld", &l, &r, &ad);
44             add(d, l, ad);
45             add(d, r + 1, -ad);
46             add(c, l, (l - 1) * ad);
47             add(c, r + 1, -ad * r);
48         }else{
49             scanf("%d%d", &l, &r);
50             ll sum1 = (l - 1) * sum(d, l - 1) - sum(c, l - 1);
51             ll sum2 = r * sum(d, r) - sum(c, r);
52             printf("%lld\n", sum2 - sum1);
53         }
54     }
55     return 0;
56 }


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: