版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82380778
学习一下蓝书上的思路,另外build函数的优化还是比较显著的
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 2000 + 10;
int data[510][510];
struct Tree {
int Max[maxn][maxn], Min[maxn][maxn], n, m;
int x1, y1, x2, y2, x, y, v, vmax, vmin, xo, xleaf, idx;
void query1(int o, int L, int R) {
if (y1 <= L && R <= y2) {
vmax = max(Max[xo][o], vmax), vmin = min(Min[xo][o], vmin);
} else {
int mid = (L + R)>>1;
if (y1 <= mid) query1(o<<1, L, mid);
if (mid < y2) query1(o<<1|1, mid+1, R);
}
}
void query2(int o, int l, int r) {
if (x1 <= l && r <= x2) { xo = o; query1(1, 1, m); }
else {
int mid = (l + r)>>1;
if (x1 <= mid) query2(o<<1, l, mid);
if (mid < x2) query2(o<<1|1, mid+1, r);
}
}
void modify1(int o, int l, int r) {
if (l == r) {
if (xleaf) { Max[xo][o] = Min[xo][o] = v; return; }
Max[xo][o] = max(Max[xo<<1][o], Max[xo<<1|1][o]);
Min[xo][o] = min(Min[xo<<1][o], Min[xo<<1|1][o]);
} else {
int mid = (l + r)>>1;
if (y <= mid) modify1(o<<1, l, mid);
else modify1(o<<1|1, mid+1, r);
Max[xo][o] = max(Max[xo][o<<1], Max[xo][o<<1|1]);
Min[xo][o] = min(Min[xo][o<<1], Min[xo][o<<1|1]);
}
}
void modify2(int o, int l, int r) {
if (l == r) { xo = o; xleaf = 1; modify1(1, 1, m); }
else {
int mid = (l + r)>>1;
if (x <= mid) modify2(o<<1, l, mid);
else modify2(o<<1|1, mid+1, r);
xo = o; xleaf = 0; modify1(1, 1, m);
}
}
void build1(int root, int l, int r) {
if (l == r) {
if (xleaf) { Max[xo][root] = Min[xo][root] = data[idx][l]; return; }
Max[xo][root] = max(Max[xo<<1][root], Max[xo<<1|1][root]);
Min[xo][root] = min(Min[xo<<1][root], Min[xo<<1|1][root]);
}
else {
int mid = (l + r)>>1;
build1(root<<1, l, mid);
build1(root<<1|1, mid+1, r);
Max[xo][root] = max(Max[xo][root<<1], Max[xo][root<<1|1]);
Min[xo][root] = min(Min[xo][root<<1], Min[xo][root<<1|1]);
}
}
void build2(int root, int l, int r) {
if (l == r) { xo = root; xleaf = 1; idx = l; build1(1, 1, m); }
else {
int mid = (l + r)>>1;
build2(root<<1, l, mid);
build2(root<<1|1, mid+1, r);
xo = root; xleaf = 0; build1(1, 1, m);
}
}
void query() { vmax = -INF; vmin = INF; query2(1, 1, n); }
void modify() { modify2(1, 1, n); }
void build() { build2(1, 1, n); }
}tree;
int main() {
int n, m, q, x1, y1, x2, y2, x, y, v;
char op[10];
scanf("%d", &n);
tree.n = n, tree.m = n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &data[i][j]);
}
}
tree.build();
scanf("%d", &q);
while (q--) {
scanf("%s", op);
if (op[0] == 'q') {
scanf("%d%d%d%d", &tree.x1, &tree.y1, &tree.x2, &tree.y2);
tree.query();
printf("%d %d\n", tree.vmax, tree.vmin);
}
else {
scanf("%d%d%d", &tree.x, &tree.y, &tree.v);
tree.modify();
}
}
return 0;
}