基础算法第三期 前缀和及差分(一维+二维)

文章目录

  • 前言
  • 一、一维前缀和及其差分
  • 二、二维前缀和及其差分
  • 总结


前言

前缀和及其差分十分重要在算法竞赛中经常用到,希望大家通过本篇文章的学习能够熟练掌握并且运用

一、(一维前缀和及其差分)

(1)一维前缀和(典型例题及其AC代码讲解)

一维前缀和公式:

基础算法第三期 前缀和及差分(一维+二维)_第1张图片

#include
using namespace std;
#include
#include
const int N=1e5+10;
int n,m,sum[N],a[N];
int main()
{
	cin>>n>>m;
	int nn;
	sum[0]=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];//这里将a数组的前n项和储存起来,即该公式即为一维前缀和
	}
	int l,r;
	while(m--){
		cin>>l>>r;
	    int maxs=max(l,r);//在这里需要判断一下大小关系
		int mini=min(l,r);
		cout<

(2)一维差分

一维差分公式:基础算法第三期 前缀和及差分(一维+二维)_第2张图片

该公式中x代表左边界,y代表右边界,z改变量,由前缀和的性质可知只需对边界进行处理即可,也就是说可以另取一个数组b进行操作在将各个区间最终的操作加起来之后,在加入到原数组当中

下面给出例题

基础算法第三期 前缀和及差分(一维+二维)_第3张图片

#include
using namespace std;

const int N=1e5+7;
int n,m,a[N],b[N],l,r,c;

void add(int x,int y,int z)//差分公式
{
	b[x]+=z;
	b[y+1]-=z;
}
int main()
{
    cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	while(m--){
		cin>>l>>r>>c;
		add(l,r,c);
	}
	for(int i=1;i<=n;i++){
		b[i]+=b[i-1];//对每一个数最终的操作
	}
	for(int i=1;i<=n;i++){
		a[i]+=b[i];//将最终的操作加到原数组当中
	}
	for(int i=1;i<=n;i++){
	    cout<

二、二维前缀和及其差分

(1)二维前缀和

二维前缀和公式:

基础算法第三期 前缀和及差分(一维+二维)_第4张图片

#include
using namespace std;

const int N=1e3+10;
int n,m,q;
int a[N][N],sum[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];
			sum[i][j]=sum[i-1][j]+sum[i][j-1]+a[i][j]-sum[i-1][j-1];//二维前缀和公式
		}
	}
	int x1,y1,x2,y2;
	while(q--){
		cin>>x1>>y1>>x2>>y2;
		cout<

(2)二维差分

二维差分公式:基础算法第三期 前缀和及差分(一维+二维)_第5张图片


tx1,ty1是起始位置,tx2,ty2,是结束的位置,c是改变量,二维差分其实用到的不算太多,不过也尽量理解着记下来,万一哪天要考到了呢

基础算法第三期 前缀和及差分(一维+二维)_第6张图片

#include
using namespace std;

const int N=1e3+10;
int a[N][N],b[N][N],sum[N][N];
int y1,x1,x2,y2,c,n,m,q;

void add(int tx1,int ty1,int tx2,int ty2,int c)//二维差分公式
{
	b[tx1][ty1]+=c;
	b[tx1][ty2+1]-=c;
	b[tx2+1][ty1]-=c;
	b[tx2+1][ty2+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];
		}
	}
	while(q--){
		cin>>x1>>y1>>x2>>y2>>c;
		add(x1,y1,x2,y2,c);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			b[i][j]+=b[i][j-1]+b[i-1][j]-b[i-1][j-1];//其实该操作与一维操作理解差不多,不过是复杂了一些,该操作相当于求每一个数的改变量
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			a[i][j]+=b[i][j];//将每一个数的改变量加入到原数组当中
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<

总结

以上就是我对该部分的理解,希望大家多多建议,谢谢大家,同时作为小白也希望能够与大家共同进步,感谢大家的观看!!!

你可能感兴趣的:(#数据结构与算法,算法)