Michael_114 @ 2024-11-30 20:32:56
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int n, q, a[501][501], ans[60001];
int disc[250001], cntdisc;
int nn;
int blockId[501], blocklen;
int rangeblockId[250001], rangeblocklen;
int counts[250001], countsum[501];
struct Position {
int x, y;
};
vector<Position> pos[250001];
struct Question {
int x1, y1, x2, y2, k, qid;
bool operator<(Question tmp) const {
if (blockId[x1] != blockId[tmp.x1]) return blockId[x1] < blockId[tmp.x1];
if (blockId[y1] != blockId[tmp.y1])
return blockId[x1] & 1 ? y1 < tmp.y1 : y1 > tmp.y1;
if (blockId[y2] != blockId[tmp.y2])
return blockId[y1] & 1 ? y2 < tmp.y2 : y2 > tmp.y2;
else
return blockId[y2] & 1 ? x2 < tmp.x2 : x2 > tmp.x2;
}
} Q[60001];
int Qcnt;
void mo_algo() {
blocklen = 11;
for (int i = 1; i <= n; ++i) blockId[i] = (i - 1) / blocklen + 1;
rangeblocklen = n + 1;
for (int i = 1; i <= nn; ++i) rangeblockId[i] = (i - 1) / rangeblocklen + 1;
counts[a[1][1]] = countsum[rangeblockId[a[1][1]]] = 1;
sort(Q + 1, Q + 1 + Qcnt);
int L = 1, R = 1, D = 1, U = 1;
for (int i = 1; i <= q; ++i) {
while (R < Q[i].y2) {
++R;
for (int i = U; i <= D; ++i)
++counts[a[i][R]], ++countsum[rangeblockId[a[i][R]]];
}
while (L > Q[i].y1) {
--L;
for (int i = U; i <= D; ++i)
++counts[a[i][L]], ++countsum[rangeblockId[a[i][L]]];
}
while (D < Q[i].x2) {
++D;
for (int i = L; i <= R; ++i)
++counts[a[D][i]], ++countsum[rangeblockId[a[D][i]]];
}
while (U > Q[i].x1) {
--U;
for (int i = L; i <= R; ++i)
++counts[a[U][i]], ++countsum[rangeblockId[a[U][i]]];
}
while (R > Q[i].y2) {
for (int i = U; i <= D; ++i)
--counts[a[i][R]], --countsum[rangeblockId[a[i][R]]];
--R;
}
while (L < Q[i].y1) {
for (int i = U; i <= D; ++i)
--counts[a[i][L]], --countsum[rangeblockId[a[i][L]]];
++L;
}
while (D > Q[i].x2) {
for (int i = L; i <= R; ++i)
--counts[a[D][i]], --countsum[rangeblockId[a[D][i]]];
--D;
}
while (U < Q[i].x1) {
for (int i = L; i <= R; ++i)
--counts[a[U][i]], --countsum[rangeblockId[a[U][i]]];
++U;
}
int res = 1, cnt = 0;
while (cnt + countsum[res] < Q[i].k && res <= rangeblockId[nn])
cnt += countsum[res], ++res;
res = (res - 1) * rangeblocklen + 1;
while (cnt + counts[res] < Q[i].k && res <= nn) cnt += counts[res], ++res;
ans[Q[i].qid] = disc[res];
}
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> q;
nn = n * n;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) {
int x;
cin >> x;
a[i][j] = disc[++cntdisc] = x;
}
sort(disc + 1, disc + 1 + cntdisc);
cntdisc = unique(disc + 1, disc + cntdisc + 1) - disc - 1;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
a[i][j] = lower_bound(disc + 1, disc + 1 + cntdisc, a[i][j]) - disc;
for (int i = 1; i <= q; ++i) {
int x1, y1, x2, y2, k;
cin >> x1 >> y1 >> x2 >> y2 >> k;
Q[++Qcnt] = {x1, y1, x2, y2, k, i};
}
mo_algo();
for (int i = 1; i <= q; ++i) cout << ans[i] << '\n';
return 0;
}
后十个点,随机TLE,无语了