差分算法的学习笔记

一般来说差分的函数是这样的

void batch_add(int l,int r,int num)
{
	b[l]+=num;
    b[r+1]-=num;
}

int main()
{
    //假设原数组a[N];
    for(int i = 1;i<=n;i++)
    {
        batch_add(1,1,a[i]);
    }
}

那原理是什么

b[1]=a[1];
b[2]=a[2]-a[1];
b[3]=a[3]-a[2];
.....
b[n]=a[n]-a[n-1];
b[n+1]=-a[n];
由此可见得到差分的两个性质:
a[n]=b[1]+b[2]...+b[n];
b[1]+b[2]+...+b[n+1]=0;

有什么用处

//对区间进行加减法
比如a[5]={1,2,3,-1,2};
要使0-3同时加1;
就可以使b[0]+1,b[3+1]-1;
为什么?
当b[0]+1时候: a[0]=b[0];a[1]=b[0]+b[1];...a[3]=b[0]+b[1]+b[2]+b[3];
然后到b[4]时候1又被减去,这就是差分的概念

差分的高阶运用
比如AcWing网站这道题目考了差分的高阶运用

也是对于区间来加减的,如果我们直接去求,我们可能选择一个一个来调节,或者同将同大同小的一起调节,很难想到把他们一起处理。

这时候我们可以运用差分来解决这个问题

5
理想1 5 3 3 4
现实1 2 2 2 1

我们就可以直接记录它们的差值来做差分
得到 0 -3 -1 -1 -3
进行差分 0 -3 2 0 -2 3
这样来看我们就可以根据b[l]+=1;b[r+1]-=1;这个概念选择一个正数和负数来进行加减
最后可以看到其实正数和是等于负数和的绝对值的,而一次操作一度,那么显然,我们的正数和就是操作的次数。

直接上代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n;
int p[N],t,b[N];

void batch_add(int l,int r,int num)
{
    b[l]+=num;
    b[r+1]-=num;
}
int main()
{
    scanf("%d",&n);
    for(int i = 1;i<=n;i++)
    {
        scanf("%d",&p[i]);
    }
    for(int i = 1;i<=n;i++)
    {
        scanf("%d",&t);
        p[i]-=t;
    }
    for(int i = 1;i<=n;i++)
    {
        batch_add(i,i,p[i]);
    }
    int sum=0;
    for(int i = 1;i<=n+1;i++){
        if(b[i]>0)
        sum+=b[i];
    }
    printf("%d",sum);
    return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值