码迷,mamicode.com
首页 > 其他好文 > 详细

[bzoj2901]矩阵求和

时间:2018-08-18 17:52:10      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:std   class   zoj   \n   size   can   $$   mes   lld   

题目大意:给出两个$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;
}

  

[bzoj2901]矩阵求和

标签:std   class   zoj   \n   size   can   $$   mes   lld   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!