1 minute read

仅记录了树状数组一些操作。

参考https://oi-wiki.org/ds/fenwick/

操作Permalink

获取ci管理的数组a中的数的个数。

int lowbit(int x) {
  return x & -x; //x + 1 = -x
}

单点修改Permalink

void add(int x, int v) {
  while (x <= n) {
    tr[x] += v;
    x += bowbit(x);
  }
}

单点查询Permalink

int getPrefix(int x) {
  int ans = 0;
  while (x) {
    ans += tr[x];
    x -= lowbit(x);
  }
  return ans;
}

区间修改Permalink

void update(int l, int r, int v) {
  add(l, v); 			//l及之后的父节点都加上v
  add(r + 1, -v); //(r + 1)及之后的父节点都减去v
}

区间查询Permalink

b是维护序列a的差分数组,由差分数组的定义,有:ai=ri=1bi,

有以下推导: ri=1ai=ri=1ij=1bj=ri=1bi×(ri+1)=ri=1bi×(r+1)ri=1bi×i

int b[MAXN], ib[MAXN]; //上述两个的数组(差分数组和数组i*bi)
int getPrefix(int* nums, int x) {
  int sum = 0, v = x + 1;
  while (x) {
    sum += v * b[x] - ib[x];
    x -= lowbit(x);
  }
  return sum;
}

int getSum(int x) {
  int ans = 0;
  while (x) {
    ans += getSum(nums, r) - getSum(nums, l - 1);
    x -= bowbit(x);
  }
  return ans;
}

构造树Permalink

int tr[MAXN];
void initBIT() {
  for (int i = 1; i <= n; i++) {
    tr[i] += a[i];						//构造前缀和
    b[i] += a[i] - a[i - 1];	//构造差分数组
    int j = i + lowbit(i);
    if (j <= n) tr[j] += tr[i];
  }
}

组合形式Permalink

1.单点修改,单点查询Permalink

2.单点修改,区间查询Permalink

3.区间修改,单点查询Permalink

4.区间修改,区间查询Permalink