前缀和
一维前缀和
就是求si=a1+a2+a3+...+ai
功能:能快速求出数组中一段数字之和
求【l,r】这一段的和=s[l]-s[r-1]
模板:
#include<iostream>
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++)//计算前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-1];//利用公式求【l,r】一段的和
}
return 0;
}
二维前缀和
功能:求一块区域内所有数字的和
求如图面积内所有数字之和
=s[i,j]-s[i-1,j]-s[i,j-1]+s[i-1,j-1]
#include <iostream>
using namespace std;
const int N = 1010;
int n, m, q;
int 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", &s[i][j]);
for (int i = 1; i <= n; i ++ )//求s[i.j]
for (int j = 1; j <= m; j ++ )
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
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;
}