一维差分的用法

一维差分

前置知识:差分数组

差分数组就是原始数组相邻元素之间的差

在这里插入图片描述

性质:

1、当它在某个区间加上一个值的时候,它的差分数组只会改变两个值,一个是区间的左端点,一个是区间的右端点的后一个值。(此时注意包含端点时,只会改变一个数据 )

例如:区间[L,R]+k

d[L]=d[L]+k d[R+1]=d[R+1]-k

2、原始数组等于上一个数组加上当前差分数组

即:a[i]=a[i-1]+d[i]

3、对于a[x]=d[1]+d[2]+……+d[x]

用法:

1、在一些求和的子问题,可以把a看作全是0的数组然后进行+

2、在一些问题可以利用差分只改变两项与只改变一项的思想,也可以用

例如:空调问题

题目要求同时将一段子数组全部加上1或者减去1, 直觉上就考虑采用差分数组的思想, 将原数组每一项的原始温度减去目标温度得到数组a, 得到每一项需要改变的数值, 然后求出a数组的差分数组b,当数组a为0时,差分数组b也为0,说明没有需要改变的数值了,所以目标是使得差分数组b的每一项变成0,

我们的操作方式有2种:(对于b)

选择任意两项, 一项加1, 另一项减1(不包含端点操作)
选择任意一项 加1 或者 减1(对a,包含端点操作)

从头开始,让他为0,(只用选择任意一项+1,或者-1,用两个数±次数保存)

显然, 使数组全部变为0的最少操作方案就是 差分数组中负数和的绝对值,正数之和的之间的最大值

此问题说明了,只要一个序列变成另一个序列都可以考虑差分

#include<iostream>

using namespace std;

const int N=1e5+10;
int f[N];//初始
int e[N];//目标
int d[N];//差分
int num1;
int num2;
int n;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) {cin>>e[i];}
    for(int i=1;i<=n;i++) {cin>>f[i];d[i]=f[i]-e[i];}
    for(int i=1;i<=n;i++)
    {
        int s=d[i]-d[i-1];
        if(s>0) num1+=s;
        else num2-=s;
    }
    cout<<max(num1,num2)<<endl;
    return 0;
}
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值