一、差分简介
一维差分结论
Acwing.797 差分
P4552 [Poetize6] IncDec Sequence - 差分思维玄学题
- 规定a数组下标从1开始 a[0]=0
- b数组下标从1开始
- 定义一个数组b,使
- 对于a数组
- 其差分数组b为
- a是b的前缀和数组
- 比如 a[2] = b[1]+b[2] = 4+4= 8
- 比如 a[4] = b[1]+b[2]+b[3]+b[4] = 4+4-2-1 = 5
- 如果我们要给a数组【l , r】区间都+c 即 a[l]+c , a[l+1]+c …… a[r]+c
- 首先给 b[l]+c 则
- 然后给 b[r+1] - c 则
先给b[l]+c 则a数组的红色区域都会+c
再给b[r+1]-c 则a数组的绿色区域都会-c
从而达到只给区间 [l,r]+c 的目的
一维差分结论
给a数组 [l,r] 区间的每个数+c,只需要给其差分数组b做如下操作即可
b[l]+=c; b[r+1]-=c;
活动 - AcWing
import java.util.*;public class Main
{static int N=(int)1e5+10;public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt(),k=sc.nextInt();int[] a=new int[N];int[] b=new int[N];for(int i=1;i<=n;i++){a[i]=sc.nextInt();b[i]=a[i]-a[i-1]; //构造差分数组}int l,r,c;while(k-->0){l=sc.nextInt();r=sc.nextInt();c=sc.nextInt();b[l]+=c;b[r+1]-=c;}for(int i=1;i<=n;i++){a[i]=a[i-1]+b[i]; //b的前缀和是aSystem.out.print(a[i]+" ");}}
}
[Poetize6] IncDec Sequence - 洛谷
思路:
这题可以转化为求出原数列的差分数组b,最后使得
题目中对数组a的操作,相当于每次能选出
中任意两个数,一个+1,一个-1
- x= b中所有正数之和
- y= b中所有负数之和的绝对值
- 我们需要先正负抵消,这时剩下最后一个数,再单独把这个数消成0
- 所以操作数就是 max(x,y)
- 求方案数 也就是求
的可能数
- 完成以上操作后得到的b差分数组就是
- 要把 x-y 消0,需要
步
- 所以b[1]会有
种方案
#include
using namespace std;const int N=1e5+10;
long long a[N],zheng,fu;int main()
{int n;cin>>n;for(int i=1;i<=n;i++) cin>>a[i];for(int i=2;i<=n;i++){int x=a[i]-a[i-1];if(x>0) zheng+=x;else fu+=abs(x);}cout<