树状数组进阶

CSDN同步

前置知识:

  • 树状数组单点修改,区间修改。

  • 差分。

下面我们考虑区间修改。

一开始我们维护的是部分前缀和,但是现在,区间修改显然不能用前缀和有关的做法。

单区间修改用差分就够了。但是这里有修改,考虑将 差分树状数组 结合。

(c)(a) 的差分,维护 (a) 的区间修改与区间和即可,这样 (a) 就是 (c) 的前缀和了。

那么区间修改只需要改 (2) 个点,单点询问只需要问前缀和。但是区间询问则怎么做?

显然,还是用前缀和相减,考虑前缀和。

那么考虑一个东西:

[sum_{i=1}^n a_i ]

[= sum_{i=1}^n sum_{j=1}^i c_j ]

[= sum_{i=1}^n c_j (n-i+1) ]

[= n imes sum_{i=1}^n c_j - sum_{i=1}^n c_i (i-1) ]

显然,前面一部分我们已经得到维护,后面我们维护 (c_i (i-1)) 即可,开两个树状数组维护。

const int N=1e5+1;
int c[N],b[N];
struct BIT {
	inline int lowbit(int x) {return x&(-x);}
	inline int sum(int x) {
		int s=0; while(x>0)
			s+=c[x]*x-b[x],x-=lowbit(x);
		return s;	
	}
	inline void update(int x,int k) {
		while(x<=n) c[x]+=k,x+=lowbit(x);
	}
} T;
原文地址:https://www.cnblogs.com/bifanwen/p/13529704.html