一维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. Orleans 整体介绍

    背景 Orleans 是微软开源的Actor模型开发框架. Actor模型 此模型解决了并发编程时对资源竞争使用的问题,将对同一个业务数据的访问从并行变为串行执行,降低了多线程编程的难度,使普通编程人 ...

  2. 2019-10-18-WPF-解决-StylusPlugIn-点击穿透问题

    title author date CreateTime categories WPF 解决 StylusPlugIn 点击穿透问题 lindexi 2019-10-18 20:55:35 +0800 ...

  3. NOIP模拟 6.26

    T1 子矩阵 题目描述 小A有一个N×M的矩阵,矩阵中1~N*M这(N*M)个整数均出现过一次.现在小A在这个矩阵内选择一个子矩阵,其权值等于这个子矩阵中的所有数的最小值.小A想知道,如果他选择的子矩 ...

  4. php语言的核心知识点

    PHP:脚本语言,网站建设,服务器端运行PHP定义:一种服务器端的 HTML 脚本/编程语言,是一种简单的.面向对象的.解释型的.健壮的.安全的.性能非常之高的.独立于架构的.可移植的.动态的脚本语言 ...

  5. windows中将网络共享文件夹映射为网络硬盘

    目的是: 实现局域网,不同电脑之间共享文件. 例如: 计划将A电脑 的文件夹C:\MM ,共享给局域网电脑 B. 局域网所有电脑都可访问: 1. 在A电脑中 共享文件夹..选择‘启用网络发现’   ‘ ...

  6. 原型模式 —— Java的赋值、浅克隆和深度克隆的区别

    赋值 直接  = ,克隆 clone 假如说你想复制一个简单变量.很简单: int a= 5; int b= a; b = 6; 这样 a == 5, b == 6 不仅仅是int类型,其它七种原始数 ...

  7. 学习JDK1.8集合源码之--Vector

    1. Vector简介 Vector是JDK1.0版本就推出的一个类,和ArrayList一样,继承自AbstractList,实现了List.RandomAccess.Cloneable.java. ...

  8. iOS 使用Quartz和OpenGL绘图

    http://blog.csdn.net/coder9999/article/details/7641701 第十二章 使用Quartz和OpenGL绘图 有时应用程序需要能够自定义绘图.一个库是Qu ...

  9. jquery的innerWidth 和 innerHeight的使用

    innerWidth This method returns the width of the element, including left and right padding, in pixels ...

  10. LintCode刷题笔记-- Count1 binary

    标签: 位运算 描述: Count how many 1 in binary representation of a 32-bit integer. 解题思路: 统计一个int型的数的二进制表现形式中 ...