差分数组及应用

差分数组
定义

对于一个有n个元素的数列d,建立一个数列d中每一项与前一项的差值的差分数组f,即当i=1时:f[1]=d[1]-0 ;当n>=2时:f[i]=d[i]-d[i-1]。

性质

计算数列各项的值。例如 d[2]=f[1]+f[2]=d[1]+d[2]-d[1],即数列第i项的值可以由差分数组的前i项的和来计算。

计算数列的前缀和。利用差分数组求出每一项再相加求和,第i项的前缀和即为数列前i项的和。

用途

快速处理区间上的加减操作:例如对数列中区间[a,b]上的数加上(或减去)x,则差分数组第一个受影响的元素为f[a],即令f[a]+=x (或f[a]-=x),后面数列元素在计算过程中都会加上x,最后一个受影响的元素为f[b],即可令f[b+1]-=x(或f[b+1]+=x),即可保证不会影响到b以后的数列中元素的计算。这样就不必对区间上的每一个数进行处理,只需处理两个差分后的数即可。

例题分析

分苹果

小朋友排成一排,老师给他们分苹果。 小朋友从左到右标号1…N。有M个老师,每次第i个老师会给第Li个到第Ri个,一共Ri-Li+1个小朋友每人发Ci个苹果。 最后老师想知道每个小朋友有多少苹果。

数据规模和约定 100%的数据,N、M≤100 000,1≤Li≤Ri≤N,0≤Ci≤100。

解题思路

苹果是连续发放的,每次改变的差分数组只有f[Li]和f[Ri+1],有M个老师发放苹果,即需要改变M次。

代码

#include<stdio.h>
int main(void){
int f[100000]; //f[i]表示第i个小朋友比第i-个小朋友多的苹果
int N,M,i,Li,Ri,Ci;
scanf(“%d%d”,&N,&M);
for(i=0;i<M;i++)
{
scanf(“%d%d%d”,&Li,&Ri,&Ci);
f[Li]+=Ci; //每一次发苹果第i个小朋友比第i-1个小朋友多Ci个
f[Ri+1]-=Ci; //第Ri+1个小朋友比第Ri个小朋友少Ci个
}
for(i=1;i<=N;i++)
{
f[i]+=f[i-1]; //根据差分数组的性质进行求和
printf("%d “,f[i]);
if(i<N)
printf(” ");
}
return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值