一维树状数组
有手就行。
#include <bits/stdc++.h>using namespace std;const int N = 1000010;int n, a[N];inline int lowbit(int x) { return x & (-x); }int ask(int x) {int res = 0;for (; x; x -= lowbit(x)) res += a[x];return res;}void add(int x, int val) {for (; x <= n; x += lowbit(x)) a[x] += val;}int query(int l, int r) {return ask(r) - ask(l - 1);}
二维树状数组
下面这个代码是用来处理差分数据的,其实单纯处理二维求和和单点修改更简单些。
#include<bits/stdc++.h>using namespace std;const int N = 1010;int n, m;int a[N][N];//原数组int d[N][N];//差分数组inline int lowbit(int x) { return x & (-x); }//对差分数组某处加上值void add(int x, int y, int val) {for (; x <= n; x += lowbit(x))for (; y <= m; y += lowbit(y))d[x][y] += val;}//对矩阵a (x1,y1)到(x2,y2)集体加上vvoid real_add(int x1, int y1, int x2, int y2, int val) {add( x1 , y1 , val);add( x1 , y2+1, -val);add(x2+1, y1 , -val);add(x2+1, y2+1, val);}//查询a[i][j]的值int query(int x, int y) {int ans = 0;for (; x; x -= lowbit(x))for (; y; y -= lowbit(y))ans += d[x][y];return ans;}
ST表
取对数不要用数学库的对数函数,那玩意复杂度不是常数,还是预处理比较好。
#include <bits/stdc++.h>using namespace std;const int N = 100010;int n;//初始数据int a[N];//ST表int ST[N][25], lg[N];void init(){//log预处理lg[1] = 0;for (int i = 2; i <= n; i++)lg[i] = lg[i / 2] + 1;//ST表预处理for (int i = 1; i <= n; ++i)ST[i][0] = a[i];for (int k = 1; k <= 20; ++k)for (int i = 1; i + (1 << k) - 1 <= n; ++i)ST[i][k] = max(ST[i][k - 1], ST[i + (1 << (k - 1))][k - 1]);}//询问inline int query(int l, int r) {int k = lg[r - l + 1];return max(ST[l][k], ST[r - (1 << k) + 1][k]);}
