zoukankan      html  css  js  c++  java
  • 树状数组(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:
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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:
    ", 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
    ", 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

  • 相关阅读:
    iOS故事板下使用代码跳转页面
    眼见不一定为实
    UITableView
    iOS 备忘录
    统计代码行数
    iOS - 图片合成
    UI 素材
    xcode中xib使用小技巧
    svn不能提交静态库解决方案
    在webSocket中获取shiro报错
  • 原文地址:https://www.cnblogs.com/LyonLys/p/BIT_Lyon.html
Copyright © 2011-2022 走看看