一维差分法

差分是前缀和的逆运算

给定一个数组a[1],a[2] ···a[n],构造b[1],b[2]···b[n]满足a[i]=b[1]+b[2]+···+b[i],即a数组是b数组的前缀和

b[1]=a[1]

b[2]=a[2]-a[1]

b[3]=a[3]-a[2]

···

b[n]=a[n]-a[n-1]

b数组就称为a数组的差分,数组a就称为数组b的前缀和

给定一个区间[l,r],使a数组在[l,r]区间内所有数都加上c,只需b[l]+c,就会使a[l]+c,a[l+1]+c···a[n]+c。但是只想让a数组[l,r]区间内加上c,第r个数往后的数不加c,就需要打一个补丁即b[r+1]-c

差分的核心操作:将a[l,r]全部加上c,等价于b[l]+=c,b[r+1]-=c

效果:

1.a[1,l-1]无影响

2.a[l,r]加上c

3.a[r+1,n]无影响

作用:时间复杂度从O(n)变成O(1)

初始化:假定a数组全部是0,则b数组也全部是0;但实际a数组是有值的,可以看成是在0的基础上进行n步插入操作:在a[1,1]加上a[1],a[2,2]加上a[2],···,a[n,n]加上a[n]

题目:

 代码:

#include<iostream>
using namespace std;
const int N=1e5+10;
int n,m;
int a[N],b[N];

//插入操作
void insert(int l,int r,int c){
    b[l]+=c;
    b[r+1]-=c;
}

int main(){
    cin>>n>>m;

    //a,b数组的初始化
    for(int i=1;i<=n;i++)cin>>a[i],insert(i,i,a[i]);

    while(m--){
        int l,r,c;
        cin>>l>>r>>c;
        insert(l,r,c);
    }

    //a数组前缀和公式
    for(int i=1;i<=n;i++)a[i]=a[i-1]+b[i],cout<<a[i]<<' ';

    return 0;
}

有关算法竞赛的题目会继续更新,欢迎评论交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值