• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LyonLys
愿意在角落唱沙哑的歌 再大声也都是给你 请用心听 不要说话 Contact me via E-mail: lyon.lys@gmail.com
博客园    首页    新随笔    联系   管理    订阅  订阅

树状数组(Binary Index Tree)

一维BIT(单点更新,区间求和):

Problem - 1166

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N = 111111;
 9 typedef long long LL;
10 inline int lowbit(int x) { return x & -x;}
11 struct BIT {
12     LL s[N], sz;
13     void init(int n) { sz = n; for (int i = 1; i <= n; i++) s[i] = 0;}
14     void add(int x, LL v) { for (x <= 0 ? 1 : x; x <= sz; x += lowbit(x)) s[x] += v;}
15     LL sum(int x) { LL r = 0; for ( ; x > 0; x -= lowbit(x)) r += s[x]; return r;}
16     LL sum(int x, int y) { return sum(y) - sum(x - 1);}
17 } bit;
18 
19 int main() {
20     //freopen("in", "r", stdin);
21     int n, m, T;
22     scanf("%d", &T);
23     for (int cas = 1; cas <= T; cas++) {
24         scanf("%d", &n);
25         bit.init(n);
26         int x, y;
27         char op[10];
28         for (int i = 1; i <= n; i++) {
29             scanf("%d", &x);
30             bit.add(i, x);
31         }
32         printf("Case %d:\n", cas);
33         while (~scanf("%s", op) && op[0] != 'E') {
34             scanf("%d%d", &x, &y);
35             if (op[0] == 'A') bit.add(x, y);
36             if (op[0] == 'S') bit.add(x, -y);
37             if (op[0] == 'Q') printf("%lld\n", bit.sum(x, y));
38         }
39     }
40     return 0;
41 }
View Code

 

一维BIT(区间求和,区间更新):

d[i]=a[i]-a[i-1](查分数组)

sigma{a[i]}=(n+1)*sigma{d[i]}-sigma{d[i]*i}

3468 -- A Simple Problem with Integers

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N = 111111;
 9 typedef long long LL;
10 inline int lowbit(int x) { return x & -x;}
11 struct BIT {
12     LL s[N], sz;
13     void init(int n) { sz = n; for (int i = 1; i <= n; i++) s[i] = 0;}
14     void add(int x, LL v) { for (x <= 0 ? 1 : x; x <= sz; x += lowbit(x)) s[x] += v;}
15     LL sum(int x) { LL r = 0; for ( ; x > 0; x -= lowbit(x)) r += s[x]; return r;}
16 } ;
17 
18 struct BIT2 {
19     BIT a, b;
20     void init(int n) { a.init(n), b.init(n);}
21     void add(int x, LL d) { a.add(x, d), b.add(x, x * d);}
22     void add(int x, int y, LL d) { add(x, d), add(y + 1, -d);}
23     LL sum(int x) { return (x + 1) * a.sum(x) - b.sum(x);}
24     LL sum(int x, int y) { return sum(y) - sum(x - 1);}
25 } bit;
26 
27 int main() {
28     //freopen("in", "r", stdin);
29     int n, m;
30     while (~scanf("%d%d", &n, &m)) {
31         bit.init(n);
32         int x, y, z;
33         char op[3];
34         for (int i = 1; i <= n; i++) {
35             scanf("%d", &x);
36             bit.add(i, i, x);
37         }
38         while (m--) {
39             scanf("%s", op);
40             if (op[0] == 'Q') {
41                 scanf("%d%d", &x, &y);
42                 printf("%lld\n", bit.sum(x, y));
43             }
44             if (op[0] == 'C') {
45                 scanf("%d%d%d", &x, &y, &z);
46                 bit.add(x, y, z);
47             }
48         }
49     }
50     return 0;
51 }
View Code

 

二维BIT(子矩阵修改,单点查询):

简单容斥一下,

add(a,b,c,d)=add(c,d)^add(c,b-1)^add(a-1,d)^add(a-1,b-1)

2155 -- Matrix

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 
 6 using namespace std;
 7 
 8 const int N = 1111;
 9 inline int lowbit(int x) { return x & -x;}
10 struct BIT2D {
11     bool s[N][N];
12     int sz;
13     void init(int n) {
14         sz = n;
15         for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) s[i][j] = 0;
16     }
17     void add(int x, int y) {
18         int t = y;
19         for ( ; x > 0; x -= lowbit(x)) {
20             for (y = t; y > 0; y -= lowbit(y)) {
21                 s[x][y] ^= 1;
22             }
23         }
24     }
25     void add(int a, int b, int c, int d) {
26         if (a > c) swap(a, c);
27         if (b > d) swap(b, d);
28         add(c, d), add(c, b - 1), add(a - 1, d), add(a - 1, b - 1);
29     }
30     bool sum(int x, int y) {
31         int t = y;
32         bool ret = 0;
33         for (x > 0 ? x : 1; x <= sz; x += lowbit(x)) {
34             for (y = t > 0 ? t : 1; y <= sz; y += lowbit(y)) {
35                 ret ^= s[x][y];
36             }
37         }
38         return ret;
39     }
40 } bit;
41 
42 int main() {
43     //freopen("in", "r", stdin);
44     int T, n, m;
45     scanf("%d", &T);
46     while (T--) {
47         scanf("%d%d", &n, &m);
48         bit.init(n);
49         char op[3];
50         int a, b, c, d;
51         while (m--) {
52             scanf("%s", op);
53             if (op[0] == 'C') {
54                 scanf("%d%d%d%d", &a, &b, &c, &d);
55                 bit.add(a, b, c, d);
56             }
57             if (op[0] == 'Q') {
58                 scanf("%d%d", &a, &b);
59                 printf("%d\n", bit.sum(a, b));
60             }
61         }
62         if (T) puts("");
63     }
64 }
View Code

 

二维BIT(单点更新,子矩阵查询):

类似上一题,

1195 -- Mobile phones

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 
 6 using namespace std;
 7 
 8 const int N = 1111;
 9 inline int lowbit(int x) { return x & -x;}
10 struct BIT2D {
11     int s[N][N];
12     int sz;
13     void init(int n) {
14         sz = n;
15         for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) s[i][j] = 0;
16     }
17     void add(int x, int y, int d) {
18         int t = y;
19         for (x = x > 0 ? x : 1; x <= sz; x += lowbit(x)) {
20             for (y = t > 0 ? t : 1; y <= sz; y += lowbit(y)) {
21                 s[x][y] += d;
22             }
23         }
24     }
25     int sum(int x, int y) {
26         int t = y;
27         int ret = 0;
28         for (; x > 0; x -= lowbit(x)) {
29             for (y = t; y > 0; y -= lowbit(y)) {
30                 ret += s[x][y];
31             }
32         }
33         return ret;
34     }
35     int sum(int a, int b, int c, int d) {
36         if (a > c) swap(a, c);
37         if (b > d) swap(b, d);
38         return sum(c, d) - sum(c, b - 1) - sum(a - 1, d) + sum(a - 1, b - 1);
39     }
40 } bit;
41 
42 int main() {
43     //freopen("in", "r", stdin);
44     int op, n;
45     while (~scanf("%d", &op)) {
46         while (op != 3) {
47             if (op == 0) {
48                 scanf("%d", &n);
49                 bit.init(n);
50             }
51             int a, b, c, d;
52             if (op == 1) {
53                 scanf("%d%d%d", &a, &b, &c);
54                 a++, b++;
55                 bit.add(a, b, c);
56             }
57             if (op == 2) {
58                 scanf("%d%d%d%d", &a, &b, &c, &d);
59                 a++, b++, c++, d++;
60                 printf("%d\n", bit.sum(a, b, c, d));
61             }
62             scanf("%d", &op);
63         }
64     }
65     return 0;
66 }
View Code

 

二维BIT(子矩阵更新,子矩阵查询):

a[i][j]——(i,j)-(n,m)增量(差分矩阵)

S[i][j]——(1,1)-(i,j)求和

S[x][y]=sigma{a[i][j]*(x-i+1)*(y-j+1)}=sigma{a[i][j]*(x+1)*(y+1)-(y+1)*a[i][j]*i-(x+1)*a[i][j]*j+a[i][j]*i*j}

令A[x][y]=sigma{a[i][j]},B[x][y]=sigma{a[i][j]*i},C[x][y]=sigma{a[i][j]*j},D[x][y]=sigma{a[i][j]*i*j}。

Problem 3132. -- 上帝造题的七分钟

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N = 2222;
 9 typedef int LL;
10 inline int lowbit(int x) { return x & -x;}
11 struct BIT {
12     LL s[N][N];
13     int n, m;
14     void init(int s1, int s2) {
15         n = s1, m = s2;
16         for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) s[i][j] = 0;
17     }
18     void add(int x, int y, int d) {
19         int t = y > 0 ? y : 1;
20         for (x = x > 0 ? x : 1; x <= n; x += lowbit(x)) {
21             for (y = t; y <= m; y += lowbit(y)) {
22                 s[x][y] += d;
23             }
24         }
25     }
26     LL sum(int x, int y) {
27         LL ret = 0;
28         int t = y > 0 ? y : 1;
29         for ( ; x > 0; x -= lowbit(x)) {
30             for (y = t; y > 0; y -= lowbit(y)) {
31                 ret += s[x][y];
32             }
33         }
34         return ret;
35     }
36 } ;
37 
38 struct BIT2 {
39     BIT A, B, C, D;
40     void init(int n, int m) { A.init(n, m), B.init(n, m), C.init(n, m), D.init(n, m);}
41     void add(int x, int y, LL k) { // add (x,y)-(n,m)
42         A.add(x, y, k), B.add(x, y, k * x), C.add(x, y, k * y), D.add(x, y, k * x * y);
43     }
44     void add(int a, int b, int c, int d, int k) {
45         if (a > c) swap(a, c);
46         if (b > d) swap(b, d);
47         add(a, b, k), add(a, d + 1, -k), add(c + 1, b, -k), add(c + 1, d + 1, k);
48     }
49     LL sum(int x, int y) { // sum (1,1)-(x,y)
50         return (x + 1) * (y + 1) * A.sum(x, y) - (y + 1) * B.sum(x, y) - (x + 1) * C.sum(x, y) + D.sum(x, y);
51     }
52     LL sum(int a, int b, int c, int d) {
53         if (a > c) swap(a, c);
54         if (b > d) swap(b, d);
55         return sum(c, d) - sum(c, b - 1) - sum(a - 1, d) + sum(a - 1, b - 1);
56     }
57 } bit;
58 
59 int main() {
60     //freopen("in", "r", stdin);
61     char op[2];
62     int a, b, c, d, e;
63     while (~scanf("%s", op)) {
64         if (op[0] == 'X') {
65             scanf("%d%d", &a, &b);
66             bit.init(a, b);
67         }
68         if (op[0] == 'L') {
69             scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
70             bit.add(a, b, c, d, e);
71         }
72         if (op[0] == 'k') {
73             scanf("%d%d%d%d", &a, &b, &c, &d);
74             printf("%d\n", bit.sum(a, b, c, d));
75         }
76     }
77     return 0;
78 }
View Code

 

二维BIT(子矩阵更新,子矩阵查询):

就是为了做这题,把一维和二维的BIT都做了一遍,原理同上题。

 Problem - 341D - Codeforces

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N = 1111;
 9 typedef long long LL;
10 inline int lowbit(int x) { return x & -x;}
11 struct BIT {
12     LL s[N][N];
13     int n, m;
14     void init(int s1, int s2) {
15         n = s1, m = s2;
16         for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) s[i][j] = 0;
17     }
18     void add(int x, int y, LL d) {
19         int t = y > 0 ? y : 1;
20         for (x = x > 0 ? x : 1; x <= n; x += lowbit(x)) {
21             for (y = t; y <= m; y += lowbit(y)) {
22                 s[x][y] ^= d;
23             }
24         }
25     }
26     LL sum(int x, int y) {
27         LL ret = 0;
28         int t = y > 0 ? y : 1;
29         for ( ; x > 0; x -= lowbit(x)) {
30             for (y = t; y > 0; y -= lowbit(y)) {
31                 ret ^= s[x][y];
32             }
33         }
34         return ret;
35     }
36 } ;
37 
38 struct BIT2 {
39     BIT A, B, C, D;
40     void init(int n, int m) { A.init(n, m), B.init(n, m), C.init(n, m), D.init(n, m);}
41     void add(int x, int y, LL k) { // add (x,y)-(n,m)
42         A.add(x, y, k);
43         //cout << x << ' ' << y << ' ' << k << "??" << endl;
44         if (x & 1) B.add(x, y, k);
45         if (y & 1) C.add(x, y, k);
46         if (x & y & 1) D.add(x, y, k);
47     }
48     void add(int a, int b, int c, int d, LL k) {
49         if (a > c) swap(a, c);
50         if (b > d) swap(b, d);
51         add(a, b, k), add(a, d + 1, k), add(c + 1, b, k), add(c + 1, d + 1, k);
52     }
53     LL sum(int x, int y) { // sum (1,1)-(x,y)
54         LL ret = D.sum(x, y);
55         if ((x ^ 1) & (y ^ 1) & 1) ret ^= A.sum(x, y);
56         if ((y ^ 1) & 1) ret ^= B.sum(x, y);
57         if ((x ^ 1) & 1) ret ^= C.sum(x, y);
58         return ret;
59     }
60     LL sum(int a, int b, int c, int d) {
61         if (a > c) swap(a, c);
62         if (b > d) swap(b, d);
63         return sum(c, d) ^ sum(c, b - 1) ^ sum(a - 1, d) ^ sum(a - 1, b - 1);
64     }
65 } bit;
66 
67 int main() {
68     //freopen("in", "r", stdin);
69     int n, m, op;
70     int a, b, c, d;
71     LL e;
72     scanf("%d%d", &n, &m);
73     bit.init(n, n);
74     while (m--) {
75         scanf("%d", &op);
76         if (op == 1) {
77             scanf("%d%d%d%d", &a, &b, &c, &d);
78             printf("%d\n", bit.sum(a, b, c, d));
79         }
80         if (op == 2) {
81             scanf("%d%d%d%d%lld", &a, &b, &c, &d, &e);
82             //cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << endl;
83             bit.add(a, b, c, d, e);
84         }
85     }
86     return 0;
87 }
View Code

 

二维BIT(单点更新,子矩阵查询): 

 Problem - 1892

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N = 1111;
 9 inline int lowbit(int x) { return x & -x;}
10 struct BIT {
11     int s[N][N], n;
12     void init(int sz) {
13         n = sz;
14         for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) s[i][j] = 0;
15     }
16     void add(int x, int y, int d) {
17         int t = y > 0 ? y : 1;
18         for (x = x > 0 ? x : 1; x <= n; x += lowbit(x)) {
19             for (y = t; y <= n; y += lowbit(y)) {
20                 s[x][y] += d;
21             }
22         }
23     }
24     int sum(int x, int y) {
25         int t = y, ret = 0;
26         for ( ; x > 0; x -= lowbit(x)) {
27             for (y = t; y > 0; y -= lowbit(y)) {
28                 ret += s[x][y];
29             }
30         }
31         return ret;
32     }
33     int sum(int a, int b, int c, int d) {
34         if (a > c) swap(a, c);
35         if (b > d) swap(b, d);
36         return sum(c, d) - sum(c, b - 1) - sum(a - 1, d) + sum(a - 1, b - 1);
37     }
38     int get(int x, int y) {
39         return sum(x, y, x, y);
40     }
41 } bit;
42 
43 int main() {
44     //freopen("in", "r", stdin);
45     int T, n;
46     scanf("%d", &T);
47     for (int cas = 1; cas <= T; cas++) {
48         bit.init(1001);
49         printf("Case %d:\n", cas);
50         int a, b, c, d, e;
51         char s[3];
52         scanf("%d", &n);
53         while (n--) {
54             scanf("%s", s);
55             if (s[0] == 'S') {
56                 scanf("%d%d%d%d", &a, &b, &c, &d);
57                 a++, b++, c++, d++;
58                 if (a > c) swap(a, c);
59                 if (b > d) swap(b, d);
60                 printf("%d\n", bit.sum(a, b, c, d) + (c - a + 1) * (d - b + 1));
61             }
62             if (s[0] == 'A') {
63                 scanf("%d%d%d", &a, &b, &c);
64                 a++, b++;
65                 bit.add(a, b, c);
66             }
67             if (s[0] == 'D') {
68                 scanf("%d%d%d", &a, &b, &c);
69                 a++, b++;
70                 c = min(c, bit.get(a, b) + 1);
71                 bit.add(a, b, -c);
72             }
73             if (s[0] == 'M') {
74                 scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
75                 a++, b++, c++, d++;
76                 e = min(e, bit.get(a, b) + 1);
77                 bit.add(a, b, -e);
78                 bit.add(c, d, e);
79             }
80         }
81     }
82     return 0;
83 }
View Code

 

——written by Lyon

posted @ 2013-09-02 23:13  LyonLys  阅读(406)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3