UVA 11297 Census——树套树

版权声明:欢迎大家转载,转载请注明出处 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;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/82380778