差分数组

转载至:zsyz_ZZY

学习差分找到了几位大佬的博客:
https://www.cnblogs.com/COLIN-LIGHTNING/p/8436624.html

https://rpdreamer.blog.luogu.org/ci-fen-and-shu-shang-ci-fen

题目:

来先看一道裸题,有n个数。

m个操作,每一次操作,将x~y区间的所有数增加z;

最后有q个询问,每一次询问求出x~y的区间和。

思路:

很明显,直接用前缀和无法快速满足这个操作,所以我们就用到了查分数组。

设a数组表示原始的数组;

设d[i]=a[i]-ai-1

设f[i]=f[i-1]+di

设sum[i]=sum[i-1]+fi

举个例子,我们求1~3的区间和.


后面的可以依次类推。

那么,对于一个操作,我们可以让d[x]加上z,让d[y+1]减小z,就可以了。

还用刚才的例子。


后面的可以依次类推。

模板代码:

#include<cstdio>

int n,m,q;
int a[100000],d[100000],f[100000],sum[100000];

int main(){
	int x,y,z;
	scanf("%d %d %d",&n,&m,&q); //输入数据 
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		d[i]=a[i]-a[i-1]; //求d[i]数组 
	}
	
	//m个操作 [x,y]区间增加z 
	for(int i=1;i<=m;i++){
		scanf("%d %d %d",&x,&y,&z);
		d[x]+=z;
		d[y+1]-=z;
	}
	
	//求解f{i]数组 和 sum[i]数组	
	for(int i=1;i<=n;i++){
		f[i]=f[i-1]+d[i];
		sum[i]=sum[i-1]+f[i];
	}
	
	//q次询问 输出sum[x,y]区间和 
	for(int i=1;i<=q;i++)
	{
		scanf("%d %d",&x,&y);
		printf("%d\n",sum[y]-sum[x-1]);
	}
}

二位前缀和:https://blog.csdn.net/k_r_forever/article/details/81775899
二维差分:https://www.cnblogs.com/sugewud/p/9937514.html

posted @ 2019-02-16 14:38  fishers  阅读(1029)  评论(0编辑  收藏  举报