差分与前缀和

本文介绍了差分与前缀和的概念及其在处理区间加常数、区间加等差数列和区间乱七八糟求和问题中的应用。通过差分数组和前缀和技巧,可以优化区间操作的复杂度,例如使用差分数组解决区间加常数问题,利用线段树处理单点修改和区间查询等。同时,文章还提供了实例分析和解题思路,如粉刷匠粉刷栅栏问题的解决方案。
摘要由CSDN通过智能技术生成

差分与前缀和

绪论

差分与前缀是两个相反的过程,其中差分旨在以递推的形式记录数组元素,前缀和是以求和的方式灵活地面对区间询问

区间加常数

给定一个序列?(初值全为0)。有很多次操作,每个操作形如: l r k

意为将?[?,?]中的每个值加上?

最后输出整个数组。 复杂度要求O(?).允许离线

这个有朴素的算法,就是老老实实一点点加,但是面对大量数据,就显得力不从心(复杂度O(n^2)).

所以我们从差分的角度思考这个问题.不妨设数组左边界为L,右边界是R,且有L<=l<=r<=R,

那么在区间加前后,除了a[l]a[r+1]元素与前一位元素的差值改变了之外,剩下的均无变化,这样也就保证了能在O(1)的时间内完成一个区间加的操作,我们不妨用数组p[]来记录差值,也就是p[i]表示a[i]-a[i-1]

综上所述

// 数组均初始化为0
int a[MAXN]; // 原数组,本质上是差分数组的前缀和
int p[MAXN]; // 差分数组
void add(int l,int r,int k){
    // 区间加,复杂度O(1)
    p[l]+=k;
    p[r+1]-=k;
}
void get_a(){
    // 生成a数组,复杂度O(n)
    for(int i=1;i<=n;++i){
    // 自1开始记数且保证a[0]为0
        a[i]=a[i-1]+p[i];
    }
}

区间加等差数列

给定一个序列?(初值全为0)。有很多次操作,操作有两种, 强制在线

  • 区间加等差数列
    指定[?,?],指定等差数列?的首项和公差。 ?[?,?]每一个元素加上对应的元素:
    ?[?] += ?1,?[?+1] += ?2,⋯
  • 单点查询
    指定?,求??.
    e.g. 目前a={1,2,3,3,3,3},给[3,5]加上首项为2、公差为1的等差数列。
    A变为: {1,2,5,6,7,3}

我们还是考虑其差分数组,对于p来说,其在(l,r]区间内的元素均加了一个常数d(公差),p[l]改为f1(首项),p[r+1]也改变了,需要减去此等差数列的最后一项

我们根据前文区间加的经验可以得知,我们只需要再创建一个数组作为p的差分数组,就可以在O(1)时间内解决这个问题,我们将这个数组命名为r[]

然后我就发现我想多了,p[]目前需要满足单点修改和区间加和区间询问,需要用线段树才能解决

区间乱七八糟求和

给定序列?,有?次询问。每次询问指定[?,?].
要你回答:
a n s = ∑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值