樹狀陣列用於變化區間的動態維護進行 \(O(logn)\) 的插入和刪除。
\(lowbit(x)\) 表示二進位制表示中最低位的1代表的值稱為最小位值,實際上就是二進位制表示中最低位的1代表的值稱為最小位值 二進位制表示中最低位的1加上後面的0的值。
設樹狀陣列\(c\), \(c_i\) 表示 ${\textstyle \sum_{i = i - lowbit(i) + 1}^{i}c[i]} $,每次修改操作只需要修改包含 \(i\) 的c, 複雜度為 \(O(logn)\)。每次查詢操作,將分段拼起來,複雜度為 \(O(logn)\)。
void init() {
for (int i = 1; i <= n; i++) {
c[i] = a[i];
}
}
int lowbit(int x) {
return x & -x;
}
void add(int x, int y) {
for (int i = x; i <= n; i += lowbit(i)) {
c[i] += y;
}
}
int sum(int x) {
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i)) {
ans += c[i];
}
return ans;
}
當需要區間修改時,就需要差分了。
\(c\) 不再需要初始值,最後加上就行。
add(u, k), add(v + 1, -k);
cout << a[u] + sum(u) << '\n';