One-dimensional prefix sum to find interval sum, two-dimensional prefix sum to find submatrix sum

One-dimensional prefix sum

The prefix sum is to store the sum of the first i items of each i before an array a in the array s respectively, namely: s[i] = s[i-1] + a[ i ];
according to the definition we can make it easier Find the interval sum, for
example, find the sum between [l, r] of array a, if we need to traverse once under normal circumstances, for(int i = l; i <= r; i++)sum += a[i]this time complexity is O(n),
if the interval range given in the question Very large and time-efficient. If the prefixes and to seek and interval, sum[l , r] = s[r] - s[l - 1]can be achieved pretreatment is O (n), the efficiency of interrogation time O (1) which greatly increases the efficiency.

template:

 s[i] = a[1] + a[2] + ... + a[i]
 a[l] + ... + a[r] = s[r] - s[l-1]

example:

Enter a sequence of integers of length n.

Next, enter m queries, and enter a pair of l, r for each query.

For each query, output the sum from the lth number to the rth number in the original sequence.

Input format The
first line contains two integers n and m.

The second row contains n integers, representing a sequence of integers.

In the next m lines, each line contains two integers l and r, representing the range of a query.

Output format
A total of m lines, each line outputs a query result.

Data range
1≤l≤r≤n,
1≤n,m≤100000,
−1000≤The value of the element in the sequence is ≤1000
Input example:

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

Sample output:

3
6
10

C++ code implementation:

#include<iostream>

using namespace std;

const int N =1e6+10; 

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;
}

Two-dimensional prefix sum

The principle of the two-dimensional prefix sum is roughly the same as the one-dimensional prefix sum, except that the two-dimensional perspective is added.
Let us first think about how to find the prefix and the array s, if the two-dimensional array is taken as an inverted plane rectangular coordinate system ij.
We use mathematical thinking to get:s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j]

Insert picture description here
We know how to get the two-dimensional prefix sum array s. Next, we need to think about what if we only need the sum of the sub-matrices?

Borrow a picture on the Internet to understand:
Insert picture description here
If we need the sum of the purple matrices in Fig. 1, we use the characteristic of the prefix sum to subtract the sum of the matrices in the blue part of Fig. 3 and Fig. 4 from the sum of the yellow matrices in Fig. 2 and find At this time, a part is subtracted, which is the green part of Figure 4, so we need to add it in the end.
which is:S = s[x2, y2] - s[x1 - 1, y2] - s[x2, y1 - 1] + s[x1 -1 , y1 - 1]

Like the above, the preprocessing efficiency is O(n), and the query efficiency is O(1)

template:

S[i, j] = 第i行j列格子左上部分所有元素的和
S[i, j] = S[i-1][j] + S[i][j-1] - S[i-1][j-1] + a[i][j](x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

Example:
Enter an integer matrix with n rows and m columns, and then enter q queries. Each query contains four integers x1, y1, x2, y2, which represent the coordinates of the upper left corner and the lower right corner of a sub-matrix.

For each query, output the sum of all numbers in the sub-matrix.

Input format The
first line contains three integers n, m, q.

The next n rows, each row contains m integers, representing a matrix of integers.

Next line q, each line contains four integers x1, y1, x2, y2, representing a set of queries.

Output format There are
q lines, and each line outputs a query result.

Data range
1≤n, m≤1000,
1≤q≤200000,
1≤x1≤x2≤n,
1≤y1≤y2≤m,
−1000≤The value of the element in the matrix≤1000
Input example:

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

Sample output:

17
27
21

C++ implementation code:

#include<iostream>

const int N = 1010;

using namespace std;

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%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;	
} 

Guess you like

Origin blog.csdn.net/diviner_s/article/details/107348741