题目
题意: 时间从n^3变为了 n^2, 进行s[]数组加的时候注意重复加入的部分,进行输出时注意多减的部分。
公式:
S[i, j] = 第i行j列格子左上部分所有元素的和
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1]
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]
代码:
#include<iostream>
using namespace std;
const int N=1010;
int n,m,q,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++)
for(int j=1;j<=m;j++)
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];//将其变为前n项和的形式
while(q--)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
printf("%d\n",s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]);//用二维前n项和进行求解
}
return 0;
}