知识点 - 树状数组
解决问题类型:
单点更新,前缀查询,很简单地拓展到2维
复杂度即代码:
//压行 #define lowbit(x) ((x)&(-(x))) void add(int x, int y) { for (; x <= idx; x += lowbit(x)) f[x] += y; } int sum(int x) { int ans = 0; for (; x; x -= lowbit(x)) ans += f[x]; return ans; }
//从0开始的BIT(下标) struct FenwickTree { vector<int> bit; // binary indexed tree int n; FenwickTree(int n) { this->n = n; bit.assign(n, 0); } FenwickTree(vector<int> a) : FenwickTree(a.size()) { for (size_t i = 0; i < a.size(); i++) add(i, a[i]); } int sum(int r) { int ret = 0; for (; r >= 0; r = (r & (r + 1)) - 1) ret += bit[r]; return ret; } int sum(int l, int r) { return sum(r) - sum(l - 1); } void add(int idx, int delta) { for (; idx < n; idx = idx | (idx + 1)) bit[idx] += delta; } }; struct FenwickTree2D { vector<vector<int>> bit; int n, m; // init(...) { ... } int sum(int x, int y) { int ret = 0; for (int i = x; i >= 0; i = (i & (i + 1)) - 1) for (int j = y; j >= 0; j = (j & (j + 1)) - 1) ret += bit[i][j]; return ret; } void add(int x, int y, int delta) { for (int i = x; i < n; i = i | (i + 1)) for (int j = y; j < m; j = j | (j + 1)) bit[i][j] += delta; } };
高维:
//三维模板 struct BIT { int a[maxn]; inline int lowbit(int x) { return x & -x; } inline int gid(int x, int y, int z) { return x * m * h + y * h + z; } void clear() { for (int i = 0; i < maxn; i++) a[i] = -inf; } void update(int x, int y, int z, int val) { for (int i = x; i <= n; i += lowbit(i)) { for (int j = y; j <= m; j += lowbit(j)) { for (int k = z; k <= h; k += lowbit(k)) { gmax(a[gid(i, j, k)], val); } } } } int query(int x, int y, int z) { int r = -inf; for (int i = x; i; i -= lowbit(i)) { for (int j = y; j; j -= lowbit(j)) { for (int k = z; k; k -= lowbit(k)) { r = max(r, a[gid(i, j, k)]); } } } return r; } } f[8];
//区间询问单点查询 void add(int idx, int val) { for (++idx; idx < n; idx += idx & -idx) bit[idx] += val; } void range_add(int l, int r, int val) { add(l, val); add(r + 1, -val); } int point_query(int idx) { int ret = 0; for (++idx; idx > 0; idx -= idx & -idx) ret += bit[idx]; return ret; }
python
//g(i) = i - (i ~&~ (-i). def sum(int r): res = 0 while (r > 0): res += t[r] r = g(r) return res def increase(int i, int delta): for all j with g(j) < i <= j: t[j] += delta
区间询问查询
def add(b, idx, x): while idx <= N: b[idx] += x idx += idx & -idx def range_add(l,r,x): add(B1, l, x) add(B1, r+1, -x) add(B2, l, x*(l-1)) add(B2, r+1, -x*r) def sum(b, idx): total = 0 while idx > 0: total += b[idx] idx -= idx & -idx return total def prefix_sum(idx): return sum(B1, idx)*idx - sum(B2, idx) def range_sum(l, r): return sum(r) - sum(l-1)
例题
- UVA 12086 - Potentiometers
- LOJ 1112 - Curious Robin Hood
- LOJ 1266 - Points in Rectangle
- Codechef - SPREAD
- SPOJ - CTRICK
- SPOJ - MATSUM
- SPOJ - DQUERY
- SPOJ - NKTEAM
- SPOJ - YODANESS
- SRM 310 - FloatingMedian
- SPOJ - Ada and Behives
- Hackerearth - Counting in Byteland
- DevSkills - Shan and String
- Codeforces - Little Artem and Time Machine
- Codeforces - Hanoi Factory
- SPOJ - Tulip and Numbers
- SPOJ - SUMSUM
- SPOJ - Sabir and Gifts
- SPOJ - The Permutation Game Again
- SPOJ - Zig when you Zag
- SPOJ - Cryon
- SPOJ - Weird Points
- SPOJ - Its a Murder
- SPOJ - Bored of Suffixes and Prefixes
- SPOJ - Mega Inversions
- Codeforces - Subsequences
- Codeforces - Ball
- GYM - The Kamphaeng Phet's Chedis
- Codeforces - Garlands
- Codeforces - Inversions after Shuffle
- GYM - Cairo Market
- Codeforces - Goodbye Souvenir
- SPOJ - Ada and Species
- Codeforces - Thor
- Latin American Regionals 2017 - Fundraising