P5953 [POI2018]Różnorodność 题解
题意
给定一个
题解
对每种元素分开算,要求的就是一些
时间复杂度:
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
int n, m, k;
std::vector<std::vector<int>> a, d;
std::map<int, int> s;
std::vector<std::vector<int>> pos;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m >> k;
a.assign(n, std::vector<int>(m));
int maxA = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
std::cin >> a[i][j];
maxA = std::max(maxA, a[i][j]);
--a[i][j];
}
}
pos.resize(maxA);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
pos[a[i][j]].push_back(i * m + j);
d.assign(n - k + 2, std::vector<int>(m - k + 2));
for (int v = 0; v < maxA; ++v) {
s.clear();
s[0] = 0;
s[m - k + 1] = -1;
for (int p : pos[v]) {
int x = p / m + 1, y = p % m + 1;
int u = std::max(0, x - k), l = std::max(0, y - k);
x = std::min(x, n - k + 1);
y = std::min(y, m - k + 1);
s[y] = std::prev(s.upper_bound(y)) -> second;
auto it = std::prev(s.upper_bound(l));
int up = std::max(it -> second, u), rt = std::next(it) -> first;
++d[up][l];
--d[up][rt];
--d[x][l];
++d[x][rt];
++it;
s[l] = x;
while (it -> first != y) {
up = std::max(it -> second, u);
int lf = it -> first;
it = s.erase(it);
rt = it -> first;
++d[up][lf];
--d[up][rt];
--d[x][lf];
++d[x][rt];
}
}
}
for (int i = 0; i <= n - k + 1; ++i)
for (int j = 1; j <= m - k + 1; ++j)
d[i][j] += d[i][j - 1];
for (int i = 1; i <= n - k + 1; ++i)
for (int j = 0; j <= m - k + 1; ++j)
d[i][j] += d[i - 1][j];
int max = 0;
long long sum = 0;
for (int i = 0; i < n - k + 1; ++i) {
for (int j = 0; j < m - k + 1; ++j) {
max = std::max(max, d[i][j]);
sum += d[i][j];
}
}
std::cout << max << " " << sum << "\n";
return 0;
}