前缀和与差分

Part 1:前缀和

定义

前缀和是指一个序列前 n 项的和。

用途

例题

输入一个长度为 n 的整数序列。接下来再输入 m 个询问,每个询问输入一对 l,r。对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。

实现

首先做一个预处理,定义一个 sum 数组,sum_i表示a_1+a_2+...a_i。对于每次查询,只需回答sum_r-sum_{l-1},时间复杂度\Theta (1)

for(int i=1;i<=n;i++)
    sum[i]=sum[i-1]+a[i];
while(q--){
    int l,r;
    cin>>l>>r;
    cout<<sum[r]-sum[l-1]<<endl;
}

Part 2:差分

定义

差分相当于前缀和的逆运算。如果 a 数组的前缀和数组是 sum,那么 a 就是 sum 的差分数组。

for(int i=1;i<=n;i++)
    diff[i]=a[i]-a[i-1];

用途

例题

给定区间[l,r],要求\Theta(1)时间内把a_l,a_{l+1},\cdots ,a_r加 c。

实现

考虑差分。

由于 a 数组是 b 数组的前缀和数组,所以对 b 数组的b_i的修改,会影响到 a 数组中从a_i及往后的每一个数。

因此我们首先让差分数组 b 中的b_l加 c,a数组变成 a_l+c,a_{l+1}+c,\cdots a_n+c。然后我们让b_{r+1}减 c,a 数组变成a_{r+1}-c,a_{r+2}-c,\cdots ,a_n-c

这样就在\Theta(1)时间内解决这个问题。

for(int i=1;i<=n;i++)
    diff[i]=a[i]-a[i-1];
while(q--){
    int l,r,c;
    cin>>l>>r>>c;
    diff[l]+=c;
    diff[r+1]-=c;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值