【复习】【差分数组】【树状数组区间修改】

差分数组的构建
即在原数列的基础上,第 n n n项与第 n − 1 n-1 n1项做差得到新数列。
a [ ] a[] a[]为原数组且 a [ 0 ] = 0 a[0]=0 a[0]=0
则差分数组 c [ ] c[] c[]中的任意一项 c [ i ] = a [ i ] − a [ i − 1 ] , i > 0 c[i]=a[i]-a[i-1],i>0 c[i]=a[i]a[i1],i>0
那么 a [ i ] = ∑ j = 1 i c [ j ] a[i]=\sum_{j=1}^ic[j] a[i]=j=1ic[j]

差分数组的应用
当我们需要对数组区间 [ x , y ] [x,y] [x,y]进行统一加减的时候,根据差分数组的性质,即 [ x , y ] [x,y] [x,y]区间的差值不变,且仅仅只有 a [ x ] − a [ x − 1 ] a[x]-a[x-1] a[x]a[x1] a [ y + 1 ] − a [ y ] a[y+1]-a[y] a[y+1]a[y]发生了变化,此时我们只需要 O ( 1 ) O(1) O(1)维护差分数组即可代替 O ( n ) O(n) O(n)的维护原数组

模板题:HDU1556

#include 
#include 
#include 
#include 
#include 
#define ll long long
#define db double
#define mx 100005 
using namespace std;
inline ll read() {
     
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){
     if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){
     x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}
ll n,a[mx];
int main() {
     
	while(true) {
     
		n=read();
		if(n==0) break;
		memset(a,0,sizeof(a));
		for(ll i=1;i<=n;i++) {
     
			ll x=read(),y=read();
			a[x]++;a[y+1]--;
		}
		for(ll i=1;i<=n-1;i++) {
     
			a[i]+=a[i-1];
			printf("%lld ",a[i]);
		}
		printf("%lld\n",a[n]+a[n-1]);
	} 
	return 0;
}

差分的应用有很多,比如树状数组区间修改、树上差分等等等
在这里就把树状数组区间修改的代码贴出来:
洛谷3368

#include 
#include 
#include 
#include 
#include 
#define ll long long
#define db double
#define mx 500005
using namespace std;
inline ll read() {
     
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){
     if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){
     x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}
ll n,m,a[mx],c[mx];
ll lowbit(ll x) {
     return x&(-x);}
ll getsum(ll x) {
     
	ll ans=0;
	while(x>0) {
     
		ans+=c[x];
		x-=lowbit(x);
	}
	return ans;
}
void update(ll x,ll y) {
     
	while(x<=n) {
     
		c[x]+=y;
		x+=lowbit(x);
	}
}
int main() {
     
	n=read(),m=read();
	for(ll i=1;i<=n;i++) {
     
		a[i]=read();
		update(i,a[i]-a[i-1]);
	}
	for(ll i=1;i<=m;i++) {
     
		ll t=read();
		if(t==1) {
     
			ll x=read(),y=read(),z=read();
			update(x,z);
			update(y+1,-z);
		} else {
     
			ll x=read();
			printf("%lld\n",getsum(x));
		}
	}
	return 0;
}

你可能感兴趣的:(复习,其他-差分,数据结构-树状数组)