[bzoj2901]矩阵求和

题目大意:给出两个$n imes n$的矩阵,$m$次询问它们的积中给定子矩阵的数值和。

题解:令为$P imes Q=R$

$$egin{align*}
&sumlimits_{i=a}^csumlimits_{j=b}^dR[i][j]\
=&sumlimits_{i=a}^csumlimits_{j=b}^dsumlimits_{k=1}^nP[i][k]cdot Q[k][j]\
=&sumlimits_{k=1}^n(sumlimits_{i=a}^cP[i][k])cdot (sumlimits_{j=b}^dQ[k][j])\
=&sumlimits_{k=1}^n(sumP[c][k]-sumP[a-1][k])(sumQ[k][d]-sumQ[k][b-1])\
end{align*}$$

卡点:

C++ Code:

#include <cstdio>
#define int long long
#define maxn 2005
using namespace std;
int n, Q, a, b, c, d, ans;
int p[maxn][maxn], q[maxn][maxn];
int sp[maxn][maxn], sq[maxn][maxn];
inline void swap(int &a, int &b) {a ^= b ^= a ^= b;}
signed main() {
	scanf("%lld%lld", &n, &Q);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) scanf("%lld", &p[i][j]), sp[i][j] = sp[i - 1][j] + p[i][j];
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) scanf("%lld", &q[i][j]), sq[i][j] = sq[i][j - 1] + q[i][j];
	}
	while (Q --> 0) {
		scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
		if (a > c) swap(a, c);
		if (b > d) swap(b, d);
		ans = 0;
		for (int i = 1; i <= n; i++) ans += (sp[c][i] - sp[a - 1][i]) * (sq[i][d] - sq[i][b - 1]);
		printf("%lld
", ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/9497641.html