自学内容网 自学内容网

前缀和与差分

前缀和与差分

差分数组的定义

差分数组 diff 是一个长度为 n 的数组,其中 diff[i] 表示原始数组 arr 中的相邻元素之差。形式化地,diff[i] = arr[i] - arr[i-1]

利用差分数组进行区间更新

差分数组的一个主要应用是进行区间更新。通过对差分数组进行操作,可以在常数时间内完成对原始数组中某个区间的增量更新。具体步骤如下:

  1. 对差分数组进行更新:对于区间 [l, r],在差分数组中 diff[l] 增加 val,而 diff[r+1] 减少 val
  2. 利用更新后的差分数组构建新的数组:从差分数组恢复原始数组 arr。遍历 diff,依次累加每个差分值,得到新的数组。

这种方法的关键在于通过更新差分数组,将区间更新的操作转化为差分数组的单点更新,从而避免了对整个区间的遍历。

int a[N];// 原数组
int diff[N];// 差分数组
int sum[N];// 前缀和数组
int diff[i];// 差分数组
// sum[i]=sum[i-1]+a[i]diff[i]=a[i]-a[i];
// 可得如下性质
  • 对原数组的差分数组求前缀和 -> 原数组
  • 对原数组的前者和数组求差分 -> 原数组

要点

利用差分和前缀和,可以离线快速O(1)进行区间修改和查询,如区间[l,r]上各个元素加x,随后查询区间某点的值。

使用示例,csp 202203-2 出行计划


// 202203-2

#include <bits/stdc++.h>
using namespace std;

const int N=200010;
int n,m,k;
int diff[N];

int main()
{
cin>>n>>m>>k;
int mx=0;
for(int i=1;i<=n;++i){
int in,c;
cin>>in>>c;
// 打疫苗区间[in-c-k+1,in-k]
// t+k<=in<=t+k+c-1 => t<=in-k t>=in-c-k+1
diff[max(1,in-c-k+1)]+=1;// max是为了防止下标为负
diff[max(1,in-k+1)]-=1;
mx=max(mx,in-k+1);
}
for(int i=1;i<=mx;++i) {
diff[i]+=diff[i-1];
}

for(int i=1;i<=m;++i){
int q;
cin>>q;
cout<<diff[q]<<endl;
}

return 0;
}

原文地址:https://blog.csdn.net/jokerMingge/article/details/135618042

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!