P1814 - [NewOJ Week 5] 矩阵 - New Online Judge (ecustacm.cn)
罗老师的题解链接:《算法竞赛·快冲300题》每日一题:“矩阵”_罗勇军的博客-CSDN博客
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2000;
int a[maxn][maxn], b[maxn][maxn], c[maxn][maxn];
int n, m;
int rd() {
int ans=0, k=1;
char ch = getchar();
while (ch=='-') {
k = -k;
ch = getchar();
}
while (ch>='0'&&ch<='9') {
ans = ans*10+(ch-'0');
ch = getchar();
}
return ans;
}
//计算前缀和。
long long query(int a1, int b1, int a2, int b2) {
long long ans = 0;
for (int i=1;i<=n;i++) {
ans += (a[a2][i]-a[a1-1][i])*(b[i][b2]-b[i][b1-1]);
}
return ans;
}
void calca() {
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
a[j][i] = a[j][i] + a[j-1][i];
}
}
}
void calcb() {
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
b[i][j] = b[i][j] + b[i][j-1];
}
}
}
signed main() {
n = rd();
m = rd();
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
a[i][j] = rd();
// cout<<a[i][j]<<" ";
}
// cout<<endl;
}
calca();
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
b[i][j] = rd();
}
}
calcb();
while (m--) {
int a1, b1, a2, b2;
a1=rd();b1=rd();a2=rd();b2=rd();
if(a1 > a2) swap(a1, a2); //可能存在a>c、b>d的情况
if(b1 > b2) swap(b1, b2);
printf("%lld\n", query(a1, b1, a2, b2));
}
return 0;
}