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

Problem - 1166

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> using namespace std; const int N = ;
typedef long long LL;
inline int lowbit(int x) { return x & -x;}
struct BIT {
LL s[N], sz;
void init(int n) { sz = n; for (int i = ; i <= n; i++) s[i] = ;}
void add(int x, LL v) { for (x <= ? : x; x <= sz; x += lowbit(x)) s[x] += v;}
LL sum(int x) { LL r = ; for ( ; x > ; x -= lowbit(x)) r += s[x]; return r;}
LL sum(int x, int y) { return sum(y) - sum(x - );}
} bit; int main() {
//freopen("in", "r", stdin);
int n, m, T;
scanf("%d", &T);
for (int cas = ; cas <= T; cas++) {
scanf("%d", &n);
bit.init(n);
int x, y;
char op[];
for (int i = ; i <= n; i++) {
scanf("%d", &x);
bit.add(i, x);
}
printf("Case %d:\n", cas);
while (~scanf("%s", op) && op[] != 'E') {
scanf("%d%d", &x, &y);
if (op[] == 'A') bit.add(x, y);
if (op[] == 'S') bit.add(x, -y);
if (op[] == 'Q') printf("%lld\n", bit.sum(x, y));
}
}
return ;
}

一维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

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> using namespace std; const int N = ;
typedef long long LL;
inline int lowbit(int x) { return x & -x;}
struct BIT {
LL s[N], sz;
void init(int n) { sz = n; for (int i = ; i <= n; i++) s[i] = ;}
void add(int x, LL v) { for (x <= ? : x; x <= sz; x += lowbit(x)) s[x] += v;}
LL sum(int x) { LL r = ; for ( ; x > ; x -= lowbit(x)) r += s[x]; return r;}
} ; struct BIT2 {
BIT a, b;
void init(int n) { a.init(n), b.init(n);}
void add(int x, LL d) { a.add(x, d), b.add(x, x * d);}
void add(int x, int y, LL d) { add(x, d), add(y + , -d);}
LL sum(int x) { return (x + ) * a.sum(x) - b.sum(x);}
LL sum(int x, int y) { return sum(y) - sum(x - );}
} bit; int main() {
//freopen("in", "r", stdin);
int n, m;
while (~scanf("%d%d", &n, &m)) {
bit.init(n);
int x, y, z;
char op[];
for (int i = ; i <= n; i++) {
scanf("%d", &x);
bit.add(i, i, x);
}
while (m--) {
scanf("%s", op);
if (op[] == 'Q') {
scanf("%d%d", &x, &y);
printf("%lld\n", bit.sum(x, y));
}
if (op[] == 'C') {
scanf("%d%d%d", &x, &y, &z);
bit.add(x, y, z);
}
}
}
return ;
}

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

简单容斥一下,

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

2155 -- Matrix

 #include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio> using namespace std; const int N = ;
inline int lowbit(int x) { return x & -x;}
struct BIT2D {
bool s[N][N];
int sz;
void init(int n) {
sz = n;
for (int i = ; i <= n; i++) for (int j = ; j <= n; j++) s[i][j] = ;
}
void add(int x, int y) {
int t = y;
for ( ; x > ; x -= lowbit(x)) {
for (y = t; y > ; y -= lowbit(y)) {
s[x][y] ^= ;
}
}
}
void add(int a, int b, int c, int d) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
add(c, d), add(c, b - ), add(a - , d), add(a - , b - );
}
bool sum(int x, int y) {
int t = y;
bool ret = ;
for (x > ? x : ; x <= sz; x += lowbit(x)) {
for (y = t > ? t : ; y <= sz; y += lowbit(y)) {
ret ^= s[x][y];
}
}
return ret;
}
} bit; int main() {
//freopen("in", "r", stdin);
int T, n, m;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
bit.init(n);
char op[];
int a, b, c, d;
while (m--) {
scanf("%s", op);
if (op[] == 'C') {
scanf("%d%d%d%d", &a, &b, &c, &d);
bit.add(a, b, c, d);
}
if (op[] == 'Q') {
scanf("%d%d", &a, &b);
printf("%d\n", bit.sum(a, b));
}
}
if (T) puts("");
}
}

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

类似上一题,

1195 -- Mobile phones

 #include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio> using namespace std; const int N = ;
inline int lowbit(int x) { return x & -x;}
struct BIT2D {
int s[N][N];
int sz;
void init(int n) {
sz = n;
for (int i = ; i <= n; i++) for (int j = ; j <= n; j++) s[i][j] = ;
}
void add(int x, int y, int d) {
int t = y;
for (x = x > ? x : ; x <= sz; x += lowbit(x)) {
for (y = t > ? t : ; y <= sz; y += lowbit(y)) {
s[x][y] += d;
}
}
}
int sum(int x, int y) {
int t = y;
int ret = ;
for (; x > ; x -= lowbit(x)) {
for (y = t; y > ; y -= lowbit(y)) {
ret += s[x][y];
}
}
return ret;
}
int sum(int a, int b, int c, int d) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
return sum(c, d) - sum(c, b - ) - sum(a - , d) + sum(a - , b - );
}
} bit; int main() {
//freopen("in", "r", stdin);
int op, n;
while (~scanf("%d", &op)) {
while (op != ) {
if (op == ) {
scanf("%d", &n);
bit.init(n);
}
int a, b, c, d;
if (op == ) {
scanf("%d%d%d", &a, &b, &c);
a++, b++;
bit.add(a, b, c);
}
if (op == ) {
scanf("%d%d%d%d", &a, &b, &c, &d);
a++, b++, c++, d++;
printf("%d\n", bit.sum(a, b, c, d));
}
scanf("%d", &op);
}
}
return ;
}

二维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. -- 上帝造题的七分钟

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> using namespace std; const int N = ;
typedef int LL;
inline int lowbit(int x) { return x & -x;}
struct BIT {
LL s[N][N];
int n, m;
void init(int s1, int s2) {
n = s1, m = s2;
for (int i = ; i <= n; i++) for (int j = ; j <= m; j++) s[i][j] = ;
}
void add(int x, int y, int d) {
int t = y > ? y : ;
for (x = x > ? x : ; x <= n; x += lowbit(x)) {
for (y = t; y <= m; y += lowbit(y)) {
s[x][y] += d;
}
}
}
LL sum(int x, int y) {
LL ret = ;
int t = y > ? y : ;
for ( ; x > ; x -= lowbit(x)) {
for (y = t; y > ; y -= lowbit(y)) {
ret += s[x][y];
}
}
return ret;
}
} ; struct BIT2 {
BIT A, B, C, D;
void init(int n, int m) { A.init(n, m), B.init(n, m), C.init(n, m), D.init(n, m);}
void add(int x, int y, LL k) { // add (x,y)-(n,m)
A.add(x, y, k), B.add(x, y, k * x), C.add(x, y, k * y), D.add(x, y, k * x * y);
}
void add(int a, int b, int c, int d, int k) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
add(a, b, k), add(a, d + , -k), add(c + , b, -k), add(c + , d + , k);
}
LL sum(int x, int y) { // sum (1,1)-(x,y)
return (x + ) * (y + ) * A.sum(x, y) - (y + ) * B.sum(x, y) - (x + ) * C.sum(x, y) + D.sum(x, y);
}
LL sum(int a, int b, int c, int d) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
return sum(c, d) - sum(c, b - ) - sum(a - , d) + sum(a - , b - );
}
} bit; int main() {
//freopen("in", "r", stdin);
char op[];
int a, b, c, d, e;
while (~scanf("%s", op)) {
if (op[] == 'X') {
scanf("%d%d", &a, &b);
bit.init(a, b);
}
if (op[] == 'L') {
scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
bit.add(a, b, c, d, e);
}
if (op[] == 'k') {
scanf("%d%d%d%d", &a, &b, &c, &d);
printf("%d\n", bit.sum(a, b, c, d));
}
}
return ;
}

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

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

Problem - 341D - Codeforces

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> using namespace std; const int N = ;
typedef long long LL;
inline int lowbit(int x) { return x & -x;}
struct BIT {
LL s[N][N];
int n, m;
void init(int s1, int s2) {
n = s1, m = s2;
for (int i = ; i <= n; i++) for (int j = ; j <= m; j++) s[i][j] = ;
}
void add(int x, int y, LL d) {
int t = y > ? y : ;
for (x = x > ? x : ; x <= n; x += lowbit(x)) {
for (y = t; y <= m; y += lowbit(y)) {
s[x][y] ^= d;
}
}
}
LL sum(int x, int y) {
LL ret = ;
int t = y > ? y : ;
for ( ; x > ; x -= lowbit(x)) {
for (y = t; y > ; y -= lowbit(y)) {
ret ^= s[x][y];
}
}
return ret;
}
} ; struct BIT2 {
BIT A, B, C, D;
void init(int n, int m) { A.init(n, m), B.init(n, m), C.init(n, m), D.init(n, m);}
void add(int x, int y, LL k) { // add (x,y)-(n,m)
A.add(x, y, k);
//cout << x << ' ' << y << ' ' << k << "??" << endl;
if (x & ) B.add(x, y, k);
if (y & ) C.add(x, y, k);
if (x & y & ) D.add(x, y, k);
}
void add(int a, int b, int c, int d, LL k) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
add(a, b, k), add(a, d + , k), add(c + , b, k), add(c + , d + , k);
}
LL sum(int x, int y) { // sum (1,1)-(x,y)
LL ret = D.sum(x, y);
if ((x ^ ) & (y ^ ) & ) ret ^= A.sum(x, y);
if ((y ^ ) & ) ret ^= B.sum(x, y);
if ((x ^ ) & ) ret ^= C.sum(x, y);
return ret;
}
LL sum(int a, int b, int c, int d) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
return sum(c, d) ^ sum(c, b - ) ^ sum(a - , d) ^ sum(a - , b - );
}
} bit; int main() {
//freopen("in", "r", stdin);
int n, m, op;
int a, b, c, d;
LL e;
scanf("%d%d", &n, &m);
bit.init(n, n);
while (m--) {
scanf("%d", &op);
if (op == ) {
scanf("%d%d%d%d", &a, &b, &c, &d);
printf("%d\n", bit.sum(a, b, c, d));
}
if (op == ) {
scanf("%d%d%d%d%lld", &a, &b, &c, &d, &e);
//cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << endl;
bit.add(a, b, c, d, e);
}
}
return ;
}

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

Problem - 1892

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> using namespace std; const int N = ;
inline int lowbit(int x) { return x & -x;}
struct BIT {
int s[N][N], n;
void init(int sz) {
n = sz;
for (int i = ; i <= n; i++) for (int j = ; j <= n; j++) s[i][j] = ;
}
void add(int x, int y, int d) {
int t = y > ? y : ;
for (x = x > ? x : ; x <= n; x += lowbit(x)) {
for (y = t; y <= n; y += lowbit(y)) {
s[x][y] += d;
}
}
}
int sum(int x, int y) {
int t = y, ret = ;
for ( ; x > ; x -= lowbit(x)) {
for (y = t; y > ; y -= lowbit(y)) {
ret += s[x][y];
}
}
return ret;
}
int sum(int a, int b, int c, int d) {
if (a > c) swap(a, c);
if (b > d) swap(b, d);
return sum(c, d) - sum(c, b - ) - sum(a - , d) + sum(a - , b - );
}
int get(int x, int y) {
return sum(x, y, x, y);
}
} bit; int main() {
//freopen("in", "r", stdin);
int T, n;
scanf("%d", &T);
for (int cas = ; cas <= T; cas++) {
bit.init();
printf("Case %d:\n", cas);
int a, b, c, d, e;
char s[];
scanf("%d", &n);
while (n--) {
scanf("%s", s);
if (s[] == 'S') {
scanf("%d%d%d%d", &a, &b, &c, &d);
a++, b++, c++, d++;
if (a > c) swap(a, c);
if (b > d) swap(b, d);
printf("%d\n", bit.sum(a, b, c, d) + (c - a + ) * (d - b + ));
}
if (s[] == 'A') {
scanf("%d%d%d", &a, &b, &c);
a++, b++;
bit.add(a, b, c);
}
if (s[] == 'D') {
scanf("%d%d%d", &a, &b, &c);
a++, b++;
c = min(c, bit.get(a, b) + );
bit.add(a, b, -c);
}
if (s[] == 'M') {
scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
a++, b++, c++, d++;
e = min(e, bit.get(a, b) + );
bit.add(a, b, -e);
bit.add(c, d, e);
}
}
}
return ;
}

——written by Lyon

树状数组(Binary Index Tree)的更多相关文章

  1. 树状数组 Binary Indexed Tree/Fenwick Tree

    2018-03-25 17:29:29 树状数组是一个比较小众的数据结构,主要应用领域是快速的对mutable array进行区间求和. 对于一般的一维情况下的区间和问题,一般有以下两种解法: 1)D ...

  2. 树状数组(Binary Indexed Tree) 总结

    1.“树状数组”数据结构的一种应用 对含有n个元素的数组(a[1],...,a[k],...,a[n]): (1)求出第i个到第j个元素的和,sum=a[i]+...+a[j]. 进行j-i+1次加法 ...

  3. 树状数组(Binary Indexed Tree(BIT))

    先不说别的,这个博客为我学习树状数组提供了很大帮助,奉上传送门 http://blog.csdn.net/int64ago/article/details/7429868 然后就说几个常用的操作 in ...

  4. 树状数组,Fenwick Tree

    Fenwick Tree, (also known as Binary Indexed Tree,二叉索引树), is a high-performance data structure to cal ...

  5. 树状数组(fenwick tree)

    树状数组又称芬威克树,概念上是树状,实际上是使用数组实现的,表现为一种隐式数据结构,balabala...详情请见:https://en.wikipedia.org/wiki/Fenwick_tree ...

  6. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  7. HDU 3436--Queue-jumpers (树状数组 or Splay Tree)

    树状数组这个真心想了好久,还是没想出来 %%% www.cppblog.com/Yuan/archive/2010/08/18/123871.html 树状数组求前缀和大于等于k的最大值,第一次看到这 ...

  8. HDU1166 敌兵布阵 BZOJ1012 最大数[树状数组]

    一.前置知识-树状数组 树状数组(binary indexed tree)是一种简洁的代码量很小的数据结构,能够高效的处理前缀区间上的问题.在很多情况下能写树状数组解决的就不用码半天线段树了. 树状数 ...

  9. NYOJ 108 士兵杀敌1(树状数组)

    首先,要先讲讲树状数组: 树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之 ...

随机推荐

  1. [转载]C语言EOF是什么?

    原贴网址:http://www.kuqin.com/language/20111112/314745.html 收藏于此: 我学习C语言的时候,遇到的一个问题就是EOF. 它是end of file的 ...

  2. 对BOM的总结

    参考:JavaScript半知半解 TG著 BOM对象 Window对象是客户端JavaScript程序的全局对象. Window对象使得JavaScript与浏览器进行交互. 所有的JavaScri ...

  3. 【JZOJ5338】【NOIP2017提高A组模拟8.25】影子 点分治?/ 排序

    题面 65 看到路径问题,就想到了套路:点分治. 对于一个分治中心,先把在其子树的结点的sum和mn求出来,分别表示该节点到分治中心的边权和和点权最小值. 然后把mn离散化,并插入权值线段树中,以su ...

  4. 【洛谷P1207】双重回文数 【USACO1.2】

    P1207 [USACO1.2]双重回文数 Dual Palindromes 题目描述 如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做"回文数".例如,12321就是一 ...

  5. webpack学习之——Entry Points(入口起点)

    1.Entry property(entry属性) 1.1 Single Entry (Shorthand) Syntax(单个入口语法) 用法:entry: string | Array<st ...

  6. FPGA按键功能

    1.如何判断按键成功按下? 2.在什么时候采集数据? 按键在按下的过程中会产生大约2ms-3ms抖动,如果此时此刻采集数据来判断按键是不准确的,那么为了采集到准确的数据需要设置一个大约10ms左右的计 ...

  7. 深入剖析Redis RDN持久化机制

    rdb是redis保存内存数据到磁盘数据的其中一种方式(另一种是AOF).Rdb的主要原理就是在某个时间点把内存中的所有数据的快照保存一份到磁盘上.在条件达到时通过fork一个子进程把内存中的数据写到 ...

  8. Minimal coverage (贪心,最小覆盖)

    题目大意:先确定一个M, 然后输入多组线段的左端和右端的端点坐标,然后让你求出来在所给的线段中能够 把[0, M] 区域完全覆盖完的最少需要的线段数,并输出这些线段的左右端点坐标. 思路分析: 线段区 ...

  9. Future Maker | 领跑亚太 进击的阿里云数据库

    7月31日,阿里云马来西亚峰会在吉隆坡召开,阿里巴巴集团副总裁.阿里云智能数据库事业部总裁李飞飞在演讲中表示:“作为亚太地区第一的云服务提供商,阿里云数据库已为多家马来西亚知名企业提供技术支持,助力企 ...

  10. JQuery-- 链式编程、静态函数,自己制作jQuery插件

    一.链式编程 为什么jQuery运行链式编程 ,让我们的代码(方法)连续不间断书写(连续调用)其实主要还是jQuery很多的函数执行完毕之后,都会返回一个jQuery对象 因为获取操作的时候,会返回获 ...