正整数
函数
方法一:拿
方法二:lowbit(x) 等于 x & -x
int lowbit(int x) {
return x & -x;
}
对正整数
例:
对比
在
给你一个长为
考虑一个跟序列
对于每个
也就是说

我们把这个序列
只要在
long long sum(int i) {
long long ans = 0;
while (i > 0) {
ans += b[i];
i -= lowbit(i); //或者写 i &= i - 1;
}
return ans;
}
在
在
对于正整数
证明都不困难。
我们说
和 相交或者不相交,指的是 和 分别对应的序列 的那一段相交或者不相交。
由此可以推得
int n; // n是序列A的长度
void add(int i, int x) {
while(i <= n) {
b[i] += x;
i += lowbit(i); //或者写 i = (i | i - 1) + 1;
}
}
从
总之,树状数组可以在
给你整数序列
区间和可以表为两个前缀和的差,有
如何从序列
法一:根据定义,算出
法二:假想一开始
Q:为什么序列
A:因为序列
依据上面两条性质,我们再给出两个构建树状数组的方法。
// 方法一
void build_fenwick(int n) {
for (int i = 1; i <= n; i++) {
b[i] += a[i];
if (i + lowbit(i) <= n)
b[i + lowbit(i)] += b[i];
}
}
// 方法二
void build_fenwick_2(int n) {
for (int i = 1; i <= n; i++) {
for (int j = lowbit(i) / 2; j > 0; j /= 2)
b[i] += b[i - j];
b[i] += a[i];
}
}
给你整数序列
考虑序列
也就是说,序列
因此我们考虑维护差分序列
给你一个长为
令
给每个
把
解法:分别维护
对于一个长为
给你一个长为
经过坐标压缩,我们有
更多人把这个处理称为「离散化」,这不恰当。
对于每个
我们可以用树状数组对每个
如果有
回想我们是如何定义一个整数序列
于是我们想到,
我们尝试把树状数组推广到一般序列上。
令
若
利用
若
若
给你
二维平面上有
有
军训时,
最初,第
在一天中发生了
教官规定不能有两个或更多学生同时离队。即在前一个离队的学生归队之后,下一个学生才能离队。因此在每一个离队的学生要归队时,队伍中有且仅有第
计算每一次离队事件中,离队的同学的编号是多少。
注意:学生的编号不会随着离队事件的发生而改变。
P3347
洛谷P1908