整体二分加上一个二维树状数组数点即可。

#include <bits/stdc++.h>
namespace IO {
char buf[1 << 21], *p1 = buf, *p2 = buf;
int p, p3 = -1;
void read() {}
inline int getc() {
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
T f = 1; x = 0;
char ch = getc();
while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getc(); }
while (isdigit(ch)) { x = x * 10 + ch - 48; ch = getc(); }
x *= f;
read(oth...);
}
}
const int N = 507;
const int M = 500 * 500 + 6e4 + 7;
int w[M], n, Q;
struct Bit {
int tree[N][N];
inline int lowbit(int x) { return x & -x; }
inline void add(int x, int y, int v) {
for (int i = x; i <= n; i += lowbit(i))
for (int j = y; j <= n; j += lowbit(j))
tree[i][j] += v;
}
inline int query(int x, int y) {
int ans = 0;
for (int i = x; i; i -= lowbit(i))
for (int j = y; j; j -= lowbit(j))
ans += tree[i][j];
return ans;
}
inline int query(int x1, int yy1, int x2, int y2) {
return query(x2, y2) + query(x1 - 1, yy1 - 1) - query(x2, yy1 - 1) - query(x1 - 1, y2);
}
} bit;
struct Node {
int x1, yy1, x2, y2, k, id;
} q[M], q1[M], q2[M];
int ans[M];
void solve(int l, int r, int L, int R) {
if (l > r || L > R) return;
if (l == r) {
for (int i = L; i <= R; i++)
if (q[i].id)
ans[q[i].id] = w[l];
return;
}
int mid = l + r >> 1;
int cnt1 = 0, cnt2 = 0;
for (int i = L; i <= R; i++) {
if (q[i].id) {
int sum = bit.query(q[i].x1, q[i].yy1, q[i].x2, q[i].y2);
if (q[i].k > sum) q[i].k -= sum, q2[++cnt2] = q[i];
else q1[++cnt1] = q[i];
} else {
if (q[i].k <= w[mid]) bit.add(q[i].x1, q[i].yy1, 1), q1[++cnt1] = q[i];
else q2[++cnt2] = q[i];
}
}
for (int i = 1; i <= cnt1; i++)
if (!q1[i].id)
bit.add(q1[i].x1, q1[i].yy1, -1);
for (int i = 1; i <= cnt1; i++)
q[L + i - 1] = q1[i];
for (int i = 1; i <= cnt2; i++)
q[L + cnt1 + i - 1] = q2[i];
solve(l, mid, L, L + cnt1 - 1);
solve(mid + 1, r, L + cnt1, R);
}
int main() {
IO::read(n, Q);
int ccnt = 0, cnt = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
int x;
IO::read(x);
w[++ccnt] = x;
++cnt;
q[cnt].x1 = i; q[cnt].yy1 = j;
q[cnt].k = x;
}
for (int i = 1; i <= Q; i++) {
++cnt;
IO::read(q[cnt].x1, q[cnt].yy1, q[cnt].x2, q[cnt].y2, q[cnt].k);
q[cnt].id = i;
}
std::sort(w + 1, w + 1 + ccnt);
ccnt = std::unique(w + 1, w + 1 + ccnt) - w - 1;
solve(1, ccnt, 1, cnt);
for (int i = 1; i <= Q; i++)
printf("%d\n", ans[i]);
return 0;
}
来源:https://www.cnblogs.com/Mrzdtz220/p/12234195.html
