前缀和差分

5.前缀和与差分


前缀和

在这里插入图片描述

输入样例:

5 3
2 1 3 6 4
1 2
1 3
2 4

输出样例:

3
6
10

模板:

//前缀和
#include<iostream> 
#include<cstdio>
using namespace std;
const int N = 100010;
int n,m;
int a[N],s[N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
	
	while(m--){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",s[r]-s[l]);
	}
	return 0;
}

 
 
 


子矩阵的和

在这里插入图片描述

输入样例:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

输出样例:

17
27
21

模板:

#include<iostream>
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],s[N][N];
int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&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;
		scanf("%d%d%d",&x1,&y1,&x2,&y2);
		printf("%d\n",s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]);//算子矩阵的和 
	} 
	return 0;
}

 
 
 


差分

在这里插入图片描述

输入样例:

6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1

输出样例:

3 4 5 3 4 2

模板:

//一维差分 
#include<iostream>
using namespace std;
const int N = 10010;
int n,m;
int a[N],b[N]; //b 是 a 的前缀和     a 是 b 的差分 
void insert(int l,int r,int c){
	b[l]+=c;
	b[r + 1]-=c;
} 
int main(){
	scanf("%d%d",&n,&m);
	
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	
	for(int i=1;i<=n;i++) insert(i,i,a[i]);  // 构造 b 使得 为 a 的差分 
	
	while(m--){
		int l,r,c;
		scanf("%d%d%d",&l,&r,&c);
		insert(l,r,c);
	}
	for(int i=1;i<=n;i++) b[i]+=b[i-1];  // b 数组变成自己的前缀和
	
	for(int i=1;i<=n;i++) printf("%d",b[i]);
	
	return 0;
}


 
 
 


差分矩阵

在这里插入图片描述

输入样例:

3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1

输出样例:

2 3 4 1
4 3 4 1
2 2 2 2

模板:

//二维差分 
#include<iostream>
#include<cstdio>
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[x2+1][y1]-=c;
	b[x1][y2+1]-=c;
	b[x2+1][y2+1]+=c; 
} 
int main(){
	scanf("%d%d%d",&n,&m,&q);
	
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++) 
	        scanf("%d",&a[i][j]);
	        
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;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++) printf("%d ",b[i][j]);
		puts("");
	}
	return 0;
	
}

 

posted @ 2022-03-22 00:44  panse·  阅读(26)  评论(0)    收藏  举报