[bzoj2901]矩阵求和
题目大意:给出两个$n\times n$的矩阵,$m$次询问它们的积中给定子矩阵的数值和。
题解:令为$P\times Q=R$
$$\begin{align*}
&\sum\limits_{i=a}^c\sum\limits_{j=b}^dR[i][j]\\
=&\sum\limits_{i=a}^c\sum\limits_{j=b}^d\sum\limits_{k=1}^nP[i][k]\cdot Q[k][j]\\
=&\sum\limits_{k=1}^n(\sum\limits_{i=a}^cP[i][k])\cdot (\sum\limits_{j=b}^dQ[k][j])\\
=&\sum\limits_{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\n", ans); } return 0; }