关于一维差分的定义,用法:
参考博客:https://blog.csdn.net/qq_41661809/article/details/86727017
一维差分例题:
https://vjudge.net/problem/HDU-1556
Color the ball
自己第一次代码TLE,因为没有省略很多东西。
第二次代码访问非法内存,因为数组开小了。
第三次代码格式错误,重新改格式。
当一维差分理解后,剩下的就是熟练:
这是个从上面链接里拿过来的可以当模板的代码:
#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];
}
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<stdio.h>
#include<string.h>
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<n;i++)
{
printf("%d ",f[i]);
}
printf("%d\n",f[n]);
}
return 0;
}
一维差分重要的点:
2 [简单性质]:
(1)计算数列各项的值:可以发现数列A的第i项的值是可以用其差分数组B的前n项和计算,即A[i]=∑B[j](1<=j<=i)
(2)计算数列的前缀和:第i项的前缀和即为数列前i项的和