【BZOJ2901】矩阵求和
Description
给出两个n*n的矩阵,m次询问它们的积中给定子矩阵的数值和。
Input
第一行两个正整数n,m。
接下来n行,每行n个非负整数,表示第一个矩阵。
接下来n行,每行n个非负整数,表示第二个矩阵。
接下来m行,每行四个正整数a,b,c,d,表示询问第一个矩阵与第二个矩阵的积中,以第a行第b列与第c行第d列为顶点的子矩阵中的元素和。
Output
对每次询问,输出一行一个整数,表示该次询问的答案。
Sample Input
3 2
1 9 8
3 2 0
1 8 3
9 8 4
0 5 15
1 9 6
1 1 3 3
2 3 1 2
1 9 8
3 2 0
1 8 3
9 8 4
0 5 15
1 9 6
1 1 3 3
2 3 1 2
Sample Output
661
388
【数据规模和约定】
对30%的数据满足,n <= 100。
对100%的数据满足,n <= 2000,m <= 50000,输入数据中矩阵元素 < 100,a,b,c,d <= n。
388
【数据规模和约定】
对30%的数据满足,n <= 100。
对100%的数据满足,n <= 2000,m <= 50000,输入数据中矩阵元素 < 100,a,b,c,d <= n。
时间限制20s
题解:一看这道题,自然想到能不能用前缀和直接搞,但是这样做可以吗?答案是可以的
时间复杂度O(nm),还有此题必须加读入优化
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn=2010; int n,m; long long ans; int sx[maxn][maxn],sy[maxn][maxn]; int rd() { int ret=0; char gc=getchar(); while(gc<'0'||gc>'9') gc=getchar(); while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret; } int main() { n=rd(),m=rd(); int i,j,a,b,c,d; for(i=1;i<=n;i++) for(j=1;j<=n;j++) sx[i][j]=sx[i-1][j]+rd(); for(i=1;i<=n;i++) for(j=1;j<=n;j++) sy[i][j]=sy[i][j-1]+rd(); for(i=1;i<=m;i++) { a=rd(),b=rd(),c=rd(),d=rd(),ans=0; if(a>c) swap(a,c); if(b>d) swap(b,d); for(j=1;j<=n;j++) ans+=(long long)(sx[c][j]-sx[a-1][j])*(sy[j][d]-sy[j][b-1]); printf("%lld\n",ans); } return 0; }
| 欢迎来原网站坐坐! >原文链接<