一维差分

关于一维差分的定义,用法:

参考博客:https://blog.csdn.net/qq_41661809/article/details/86727017

一维差分例题:

https://vjudge.net/problem/HDU-1556

Color the ball

HDU - 1556


自己第一次代码TLE,因为没有省略很多东西。

第二次代码访问非法内存,因为数组开小了。

第三次代码格式错误,重新改格式。


当一维差分理解后,剩下的就是熟练:

这是个从上面链接里拿过来的可以当模板的代码:

#include	
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];

	}	
	for(int i=1;i<=m;i++)
	{		

	scanf("%d %d %d",&x,&y,&z);	

	d[x]+=z;	

	d[y+1]-=z;	

	}			

	for(int i=1;i<=n;i++)

	{
	 
	 f[i]=f[i-1]+d[i];	

	 sum[i]=sum[i-1]+f[i];
	
	}
	
	for(int i=1;i<=q;i++)
	{	
	
	   scanf("%d %d",&x,&y);	
	
	   printf("%d\n",sum[y]-sum[x-1]);
	}
}

在这道hdu题目的基础上,因为a[i]刚开始都是0,直接d[i]就好,sum[i]也没有必要。


这道题的代码:

#include
#include
int d[100010],f[100010];
int main()
{
	int n,i,x,y,z;
	while(scanf("%d", &n)!=EOF)
	{
		if(n==0)
		break;
		memset(d,0,sizeof(d));
		memset(f,0,sizeof(f));
		for(i=1;i<=n;i++)
		{
			scanf("%d%d", &x, &y);
			d[x]+=1;
			d[y+1]-=1;
		}
	    for(i=1;i<=n;i++)
		{
		  f[i]=f[i-1]+d[i];	
		}
		for(i=1;i

一维差分重要的点:

2 [简单性质]

(1)计算数列各项的值:可以发现数列A的第i项的值是可以用其差分数组B的前n项和计算,即A[i]=∑B[j](1<=j<=i)

(2)计算数列的前缀和:第i项的前缀和即为数列前i项的和

3[用途]:

          (1)  快速处理区间加减操作:

             如果进行区间加减操作,且修改的区间连续,那么若将[x,y]区间内A[i]各加val,我们就可以只对其差分数组B的x和y这两               项进行修改,x项B[x]加val ,y项 B[y+1]减val。

          (2)  询问区间和问题:

             在保证(1)正确修改的基础上,我们可以由性质(2)计算出数列各项的前缀和数组sum各项的值;那么显然,区间                   [L,R]的和即A[L]+…+A[R] = ans = sum[R]-sum[L-1].
————————————————
摘自:https://blog.csdn.net/qq_41661809/article/details/86727017

你可能感兴趣的:(#,差分,一维差分)