資料結構
Review
Sparse Table
Binary Indexed Tree
Segment Tree
簡報自己讀不懂很正常他偏抽象
預習
1. 區間查詢
2. 前綴和
Range Queries
區間查詢
Range Sum
區間和
for (int i = l; i <= r; i++) {
sum += arr[i];
}
Range Sum
區間和
Range Sum
區間和
Range Sum
區間和
題目
稀疏表
Minimum Queries
Minimum Queries
區間最小值
Minimum Queries
區間最小值
Implement
vector<vector<int>> st(__lg(n) + 1, vector<int>(n));
for (int i = 0; i < n; i++) st[0][i] = arr[i];
for (int i = 1; i <= __lg(n); i++) {
int len = 1 << (i - 1);
for (int j = 0; j < n; j++) {
st[i][j] = min(st[i - 1][j], st[i - 1][j + len]);
}
}
int query(int l, int r) {
int k = __lg(r - l + 1);
return min(st[k][l], st[k][r - (1 << k) + 1]);
}
題目
樹狀陣列(二元索引樹)
Dynamic Range Sum Queries
Range Sum
區間和
Binary Indexed Tree (BIT)
aka Fenwick Tree
Binary Indexed Tree (BIT)
Binary Indexed Tree (BIT)
Binary Indexed Tree (BIT)
Implement
Implement
Implement
void add(int k, int x) {
while (k <= n) {
tree[k] += x;
k += k & -k;
}
}
int sum(int k) {
int ret = 0; // return
while (k) { // while k >= 1
ret += tree[k];
k -= k & -k;
}
return ret;
}
Other Technique
Other Technique
題目
線段樹
Dynamic Range Queries
Segment Tree
線段樹
Implement
Implement
Implement
Segment Tree
Implement
void add(int k, int x) {
k += n; // 先移到對應位置
tree[k] += x;
for (k /= 2; k > 0; k /= 2) {
tree[k] = tree[2 * k] + tree[2 * k + 1];
}
}
int sum(int l, int r) {
l += n, r += n;
int ret = 0;
while (l <= r) {
// 如果父節點會超出範圍就縮進來
if (l % 2 == 1) ret += tree[l++];
if (r % 2 == 0) ret += tree[r--];
l /= 2, r /= 2; // 移動到上一層
}
return ret;
}
Implement
struct segmentTree {
int n;
segmentTree(vector<int> data) : n(data.size()) {
data.resize(n * 4);
build(1, 1, n, data);
}
void build(int id, int l, int r, vector<int> data) {
if (l == r) {
tree[id] = data[l];
return;
}
int mid = (l + r) / 2;
build(id * 2, l, mid, data);
build(id * 2 + 1, mid + 1, r, data);
tree[id] = tree[id * 2] + tree[id * 2 + 1];
}
void add(int id, int k, int x, int l, int r) {
if (l == r) {
tree[id] += x;
return;
}
int mid = (l + r) / 2;
if (k <= mid) modify(id * 2, k, x, l, mid);
else modify(id * 2 + 1, k, x, mid + 1, r);
tree[id] = tree[id * 2] + tree[id * 2 + 1];
}
int sum(int id, int l, int r, int L, int R) {
if (l <= L && R <= r) {
return tree[id];
}
int mid = (l + r) / 2;
int ret = 0;
if (L <= mid) ret += query(id * 2, l, mid, L, R);
if (R > mid) ret += query(id * 2 + 1, mid + 1, r, L, R);
return ret;
}
};
題目