能解决什么问题
动态求连续区间和
对于数组 a[N] 可以求出在 a[i] 左边大于 a[i] 的数的个数,在 a[i] 右边小于 a[i] 的值
时间复杂度
O(log n)
代码
int tr[N];
int lowbit(int x)
{
return x & -x;
}
void add(int x, int v)
{
for (int i = x; i < N; i += lowbit(i)) tr[i] += v;
}
void query(int x)
{
int res = 0;
for (int i = x; i > 0; i -= lowbit(i)) res += tr[i];
return res;
}
// 求 a[0, i - 1] 比 a[i] 大的数的个数
for (int i = 0; i < n; i++) {
sum[i] += query(N - 1) - query(h[i]);
add(a[i], 1);
}
memset(tr, 0, sizeof tr);
// 求 a[i + 1, n - 1] 比 a[i] 小的数的个数
for (int i = n - 1; i >= 0; i--) {
sum[i] += query(a[i] - 1);
add(a[i], 1);
}