前缀和与二维前缀和
前缀和与二维前缀和
前缀和
前缀和的作用主要是用来快速求出 数组中某一连续段落的和
首先需要对前缀和数组进行预处理
S[ i ] 表示前 i 个元素的和,在输入时 S[ i ] = S[ i-1 ] + a[ i ];
在处理前缀和时下标一般选为 1 — n,因为每次都是用 S[j] - S[i -1]
为了代码中格式统一,即使S[n]就是前n项的前缀和,我们仍然使用 S[ n ] - S[ 0 ]
这样为了不越界,就将范围定为 1 — n,将S[0] 定为 0
在求某段连续段落的和时,如果采用数组遍历的方式 将a[ i ] + ..... +a[ j ] 时间复杂度为 O(n)
而使用前缀和的话,只需要 S[ j ] - S[ i -1 ] 即可,时间复杂度为O( 1 )
题目

输入
5 3 2 1 3 6 4 1 2 1 3 2 4
期望输出
3 6 10
题解
#include<bits/stdc++.h> using namespace std;
int n,m; const int N=1e6+10; int a[N],s[N]; int main() { cin>>n>>m; /** 在处理前缀和时下标一般选为 1 — n,因为每次都是用 S[j] - S[i -1] 为了代码中格式统一,即使S[n]就是前n项的前缀和,我们仍然使用 S[ n ] - S[ 0 ] 这样为了不越界,就将范围定为 1 — n,将S[0] 定为 0 **/ for(int i=1;i<=n;i++) { scanf("%d",&a[i]); s[i] = s[i-1] + a[i]; } while(m--) { int l ,r; cin>>l>>r; cout<< s[r] - s[l-1]<<endl; } }
二位前缀和
二位前缀和表达的含义 S[ i , j ] 是从 (0.0) 到 (i,j)这一矩形 范围内的元素的和
题目

输入
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<bits/stdc++.h>
using namespace std;
const int N =1e3+9;
int n,m,q;
int a[N][N],s[N][N];
int main()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)//与一维一致,范围都是1-n
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][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;
int ans ;
ans =s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];//计算区间内部数值和
cout<<ans<<endl;
}
}

浙公网安备 33010602011771号