Submission #894000

# Submission time Handle Problem Language Result Execution time Memory
894000 2023-12-27T18:36:29 Z azosi Min-max tree (BOI18_minmaxtree) C++17
29 / 100
187 ms 27940 KB
#include <bits/stdc++.h>

using namespace std;
const int MAX_N = 70070;
const int INF = 1e9 + 100;
int n, q;

struct SegmentTree {
    typedef int (*F)(int, int);

    F merge;
    int identity;
    int tree[MAX_N * 4]{}, lazy[MAX_N * 4]{};

    SegmentTree(F func, int identity) : merge(func), identity(identity) {
        for (int i = 0; i < MAX_N * 4; ++i) tree[i] = lazy[i] = identity;
    }

    void push(int node, int l, int r) {
        if (lazy[node] != identity) {
            tree[node] = merge(tree[node], lazy[node]);
            if (l != r) {
                lazy[node * 2] = merge(lazy[node * 2], lazy[node]);
                lazy[node * 2 + 1] = merge(lazy[node * 2 + 1], lazy[node]);
            }
        }
        lazy[node] = identity;
    }

    void update(int s, int e, int val, int node = 1, int l = 1, int r = MAX_N) {
        push(node, l, r);
        if (e < l || r < s) return;
        if (s <= l && r <= e) {
            lazy[node] = val;
            push(node, l, r);
            return;
        }
        int mid = (l + r) / 2;
        update(s, e, val, node * 2, l, mid);
        update(s, e, val, node * 2 + 1, mid + 1, r);
        tree[node] = merge(tree[node * 2], tree[node * 2 + 1]);
    }

    int query(int s, int e, int node = 1, int l = 1, int r = MAX_N) {
        push(node, l, r);
        if (e < l || r < s) return identity;
        if (s <= l && r <= e) return tree[node];
        int mid = (l + r) / 2;
        return merge(query(s, e, node * 2, l, mid), query(s, e, node * 2 + 1, mid + 1, r));
    }

};

int _mn(int a, int b) {
    return min(a, b);
}

int _mx(int a, int b) {
    return max(a, b);
}

SegmentTree minSeg(_mn, INF), maxSeg(_mx, -INF);
int in[MAX_N], dep[MAX_N], par[MAX_N], top[MAX_N], sz[MAX_N], chk[MAX_N];
int pv;
vector<int> g[MAX_N], inp[MAX_N];

void dfs(int v = 1) {
    chk[v] = 1;
    for (auto i: inp[v]) {
        if (chk[i]) continue;
        chk[i] = 1;
        g[v].push_back(i);
        dfs(i);
    }
}

void dfs1(int v = 1) {
    sz[v] = 1;
    for (auto &i: g[v]) {
        dep[i] = dep[v] + 1;
        par[i] = v;
        dfs1(i);
        sz[v] += sz[i];
        if (sz[i] > sz[g[v][0]]) swap(i, g[v][0]);
    }
}

void dfs2(int v = 1) {
    in[v] = ++pv;
    for (auto i: g[v]) {
        top[i] = i == g[v][0] ? top[v] : i;
        dfs2(i);
    }
}

void update(int a, int b, int op, int k) {
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]]) swap(a, b);
        int st = top[a];
        if (op == 1) minSeg.update(in[st], in[a], k);
        else maxSeg.update(in[st], in[a], k);
        a = par[st];
    }
    if (dep[a] > dep[b]) swap(a, b);
    if (op == 1) minSeg.update(in[a] + 1, in[b], k);
    else maxSeg.update(in[a] + 1, in[b], k);
}

int mn[MAX_N], mx[MAX_N], cnt[MAX_N], ans[MAX_N];
vector<int> bench[MAX_N];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n;
    top[1] = 1;
    for (int i = 2; i <= n; i++) {
        int s, e;
        cin >> s >> e;
        inp[s].push_back(e);
        inp[e].push_back(s);
    }
    dfs();
    dfs1();
    dfs2();

    cin >> q;
    vector<int> zz;
    for (int i = 0; i < q; i++) {
        char op;
        int a, b, c;
        cin >> op >> a >> b >> c;
        if (op == 'm') update(a, b, 2, c);
        else update(a, b, 1, c);
        zz.push_back(c);
    }
    sort(zz.begin(), zz.end());
    zz.resize(unique(zz.begin(), zz.end()) - zz.begin());
    memset(mx, -1, sizeof(mx));
    memset(mn, -1, sizeof(mn));
    memset(chk, 0, sizeof(chk));
    for (auto &i: ans) i = INF;
    for (int i = 2; i <= n; ++i) {
        int mini = minSeg.query(in[i], in[i]);
        int maxi = maxSeg.query(in[i], in[i]);
        if (mini != INF) {
            mn[i] = lower_bound(zz.begin(), zz.end(), mini) - zz.begin();
            bench[mn[i]].push_back(i);
        }
        if (maxi != -INF) {
            mx[i] = lower_bound(zz.begin(), zz.end(), maxi) - zz.begin();
            bench[mx[i]].push_back(i);
        }
    }
    set<pair<int, int>> s;
    for (int i = 0; i < zz.size(); ++i) {
        cnt[i] = bench[i].size();
        s.insert({bench[i].size(), i});
    }
    while (!s.empty()) {
        int id = s.begin()->second;
        s.erase(s.begin());
        chk[id] = 1;
        int v = 0;
        for (auto node: bench[id])
            if (ans[node] == INF) {
                v = node;
                break;
            }
        if (mn[v] != -1 && !chk[mn[v]]) {
            s.erase({cnt[mn[v]], mn[v]});
            cnt[mn[v]]--;
            s.insert({cnt[mn[v]], mn[v]});
        }
        if (mx[v] != -1 && !chk[mx[v]]) {
            s.erase({cnt[mx[v]], mx[v]});
            cnt[mx[v]]--;
            s.insert({cnt[mx[v]], mx[v]});
        }
        ans[v] = zz[id];
    }
    for (int i = 2; i <= n; ++i) {
        cout << i << ' ' << par[i] << ' ';
        if (ans[i] != INF)
            cout << ans[i];
        else {
            if (mn[i] != -1) {
                cout << zz[mn[i]];
            } else {
                cout << 0;
            }
        }
        cout << '\n';
    }

}

Compilation message

minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:157:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  157 |     for (int i = 0; i < zz.size(); ++i) {
      |                     ~~^~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 3 ms 12380 KB Output is correct
2 Correct 3 ms 12380 KB Output is correct
3 Correct 3 ms 12380 KB Output is correct
4 Correct 3 ms 12380 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 135 ms 26576 KB Output is correct
2 Correct 187 ms 22508 KB Output is correct
3 Correct 148 ms 24528 KB Output is correct
4 Correct 155 ms 27940 KB Output is correct
5 Correct 148 ms 24232 KB Output is correct
6 Correct 134 ms 23628 KB Output is correct
7 Correct 123 ms 22984 KB Output is correct
# Verdict Execution time Memory Grader output
1 Incorrect 115 ms 18516 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 12380 KB Output is correct
2 Correct 3 ms 12380 KB Output is correct
3 Correct 3 ms 12380 KB Output is correct
4 Correct 3 ms 12380 KB Output is correct
5 Correct 135 ms 26576 KB Output is correct
6 Correct 187 ms 22508 KB Output is correct
7 Correct 148 ms 24528 KB Output is correct
8 Correct 155 ms 27940 KB Output is correct
9 Correct 148 ms 24232 KB Output is correct
10 Correct 134 ms 23628 KB Output is correct
11 Correct 123 ms 22984 KB Output is correct
12 Incorrect 115 ms 18516 KB Output isn't correct
13 Halted 0 ms 0 KB -