一、一维前缀和
数组每一位代表到这一位的累积和,因此要得到[l,r]区间内的累积和,用sum[r]-sum[l-1]即可。
这个比较简单直接看代码就能理解:
例题链接:https://ac.nowcoder.com/acm/problem/226282
完整ac代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,q;
cin>>n>>q;
vector<long long> sum(n+1);
sum[0]=0; // 初始化前缀和数组
for(int i=1;i<=n;i++){
long long x;
cin>>x;
sum[i]=sum[i-1]+x; // 计算前缀和
}
while(q--){
int l,r;
cin>>l>>r;
cout<<sum[r]-sum[l-1]<<endl; // 输出区间和
}
return 0;
}
二、二维前缀和
1、二维前缀和原理
二维前缀和的思路是利用动态规划的思想,在二维数组中预处理出每个位置(i,j)对应的矩阵区域的和。这样可以在O(1)的时间复杂度内查询任意矩阵区域的和。
2、核心代码
// 遍历二维数组,读取每个位置的值并计算二维前缀和
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
long long x;
cin >> x;
// 计算二维前缀和,当前位置的值等于当前位置的值加上其上方、左方、左上方三个位置的值之和减去左上方位置的值
a[i][j] = x + a[i-1][j] + a[i][j-1] - a[i-1][j-1];
}
}
3、完整代码及例题
例题:https://ac.nowcoder.com/acm/problem/226333
完整ac代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, m, q;
cin >> n >> m >> q;
// 初始化二维数组a,并计算二维前缀和
vector<vector<long long>> a(n+1, vector<long long>(m+1, 0));
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
long long x;
cin >> x;
// 计算二维前缀和,当前位置的值等于当前位置的值加上其上方、左方、左上方三个位置的值之和减去左上方位置的值
a[i][j] = x + a[i-1][j] + a[i][j-1] - a[i-1][j-1];
}
}
// 查询矩阵区域的和并输出结果
while(q--){
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
// 输出矩阵区域的和,利用二维前缀和的性质计算
cout << a[x2][y2] - a[x1-1][y2] - a[x2][y1-1] + a[x1-1][y1-1] << endl;
}
return 0;
}