题解:P12561 [UTS 2024] Matrix
xubaichuan · · 题解
题解都在干什么,这题难道不是裸的三维数点吗?
考虑什么时候
其中,第三个条件等价于:
因为这题前两维限制都在矩阵上,所以不需要显式实现 CDQ。算上树状数组,总时间复杂度
不管是时间还是空间,这个做法的常数都很小,不怎么卡常。注意一下常数,就能拿下最优解 rk1。
参考代码(非最优解版本):
#include <bits/stdc++.h>
using namespace std;
using info = array<int, 2>;
info operator + (const info& a, const info& b) {
if (a[0] > b[0]) {
return a;
} else if (a[0] < b[0]) {
return b;
} else {
return {a[0], a[1] + b[1]};
}
}
template<int N>
struct Fenwick {
info tr[N];
void clear() {
fill(tr, tr + N, info{-1, 0});
}
void add(int i, info v) {
for (; i < N; i += i & -i) {
tr[i] = tr[i] + v;
}
}
info query(int i) {
i = min(i, N - 1);
info res{-1, 0};
for (; i > 0; i -= i & -i) {
res = res + tr[i];
}
return res;
}
};
const int N = 2005;
int n, m, k, a[N][N];
info ans[N][N];
Fenwick<N * 2> fw;
void solve(int l, int r) {
if (l == r) {
fw.clear();
for (int i = 1; i <= n; i++) {
fw.add(l - i + n, {a[i][l], 1});
ans[i][l] = ans[i][l] + fw.query(l - i + n + k - 1);
}
return ;
}
int mid = l + r >> 1;
solve(l, mid);
solve(mid + 1, r);
fw.clear();
for (int i = 1; i <= n; i++) {
for (int j = mid + 1; j <= r; j++) {
fw.add(j - i + n, {a[i][j], 1});
}
for (int j = l; j <= mid; j++) {
ans[i][j] = ans[i][j] + fw.query(j - i + n + k - 1);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
ans[i][j] = {-1, 0};
}
}
solve(1, m);
for (int i = k; i <= n; i++) {
for (int j = 1; j + k - 1 <= m; j++) {
cout << ans[i][j][0] << ' ';
}
cout << '\n';
}
for (int i = k; i <= n; i++) {
for (int j = 1; j + k - 1 <= m; j++) {
cout << ans[i][j][1] << ' ';
}
cout << '\n';
}
return 0;
}