前缀和差分是互相的逆运算
前缀
注:S数组为前缀和数组,a数组储存的是原数组。
一维前缀和
一维前缀和是求数组的前n个数的和,定义为:
在求的时候可以用如下公式:
一唯前缀和的主要应用是求 的值:
主要是用于降低时间复杂度,在每次求到的和的时候,能够将时间复杂度从降低到。
二维前缀和
二维前缀和较一维前缀和较为复杂,需要用到矩阵的相关知识。
二维前缀和主要用于求 到 这部分内的所有数的和:
在求前缀和的时候用到如下公式:
同样,二维前缀和的作用也是为了降低时间复杂度。
代码模板
一维前缀和
/*IndexYang 2021-11-03*/
#include <iostream>
using namespace std;
const int N = 100010;
int n,m;
int a[N],s[N];
int main(){
s[0] = 0;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) s[i] = s[i-1]+a[i]; //求前缀和
while(m--){
int l,r;
cin>>l>>r;
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}
二维前缀和
/*IndexYang 2021-11-03*/
#include<iostream>
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],s[N][N];
int main(){
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j]; //求前缀和矩阵
while(q--){
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
cout<<s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]<<endl; //求此区域内的数字和
}
return 0;
}
例题
--模板即例题--
差分
一维差分
给定一个原数组a:
构造一个数组b:
使得
也就是说a数组是b数组的前缀和数组,即b数组则是a数组的差分数组 在构造b数组的时候可以用到如下公式:
差分最主要的应用是给a数组中的[l,r]区间中的每一个数都加上c,只需对差分数组b做
再求前缀和就行了。时间复杂度为, 大大提高了效率。
二维差分
代码模板
一维差分
/*IndexYang 2021-11-05*/
# include<iostream>
using namespace std;
const int N = 1000010;
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;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) insert(i,i,a[i]);//将原数组的n个数先插入进去,这里是初始化差分数组
while(m--){
int l,r,c;
cin>>l>>r>>c;
insert(l,r,c); //表示将[l,r]区间上的每个数都加上c
}
for(int i=1;i<=n;i++){
b[i] += b[i-1];//将构造的b的差分数组进行求前缀和,恢复成a数组
printf("%d ",b[i]); //输出每个都加上c之后的前缀和数组
}
return 0;
}
二维差分
/*IndexYang 2021-11-05*/
#include <iostream>
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],b[N][N];
void insert(int x1,int y1,int x2,int y2,int c){
b[x1][y1] += c;
b[x1][y2+1] -= c;
b[x2+1][y1] -= c;
b[x2+1][y2+1] += c;
}
int main(){
cin>>n>>m>>q;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
insert(i,j,i,j,a[i][j]);
}
}
while(q--){
int x1,y1,x2,y2,c;
cin>>x1>>y1>>x2>>y2>>c;
insert(x1,y1,x2,y2,c);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
b[i][j] += b[i-1][j] + b[i][j-1] - b[i-1][j-1];
printf("%d ",b[i][j]);
}
puts("");
}
return 0;
}
例题
--模板即例题--