Submission #1370882

#TimeUsernameProblemLanguageResultExecution timeMemory
1370882domiBirthday gift (IZhO18_treearray)C++20
0 / 100
13 ms19300 KiB
#include <bits/stdc++.h>

#define int long long
#define fi first
#define se second

#define sz(a) (int)((a).size())
#define all(a) (a).begin(), (a).end()

#define lsb(x) (x & (-x))
#define vi vector<int>
#define YES { cout << "YES" << endl; return; }
#define NO { cout << "NO" << endl; return; }

using ll = long long;
using pii = std::pair<int, int>;

const int NMAX = 2e5;
const int LOG = 18;

using namespace std;

namespace Tree {
    vector<int> T[NMAX + 5];
    int up[NMAX + 5][LOG + 5];
    int tin[NMAX + 5];
    int tout[NMAX + 5];
    int timer;
    int N;

    inline void add_edge(int u, int v) {
        T[u].push_back(v);
        T[v].push_back(u);
        N = max({N, u, v});
    }

    void dfs(int nod, int p = 0) {
        tin[nod] = ++timer;
        up[nod][0] = p;
        for (auto &son : T[nod]) {
            if (son == p) continue;
            dfs(son, nod);
        }
        tout[nod] = timer;
    }

    bool is_anc(int u, int v){
        return (tin[u] <= tin[v] && tout[v] <= tout[u]);
    }

    void init() {
        dfs(1);
        for (int k = 1; k <= LOG; ++k) {
            for (int u = 1; u <= N; ++u)
                up[u][k] = up[up[u][k - 1]][k - 1];
        }
    }

    inline int lca(int u, int v) {
        if (is_anc(u, v)) return u;
        if (is_anc(v, u)) return v;

        for (int k = LOG; k >= 0; --k) {
            if (up[u][k] && !is_anc(up[u][k], v))
                u = up[u][k];
        }

        return up[u][0];
    }
}

using namespace Tree;

set<pair<int, int>> two[NMAX + 5];
set<int> one[NMAX + 5];
int a[NMAX + 5], n, m, q;

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cin >> n >> m >> q;

    for (int i = 0, u, v; i < n - 1; ++i) {
        cin >> u >> v;
        Tree::add_edge(u, v);
    }

    for (int i = 1; i <= m; ++i)
        cin >> a[i];

    Tree::init();
    for (int i = 1; i <= m; ++i) {
        one[a[i]].insert(i);
        if (i > 1)
            two[lca(a[i - 1], a[i])].insert({i - 1, i});
    }

    for (int i = 0, op, l, r, pos, v; i < q; ++i) {
        cin >> op;

        if (op == 1) {
            cin >> pos >> v;
            one[a[pos]].erase(pos);
            if (pos > 1)
                two[lca(a[pos - 1], a[pos])].erase({pos - 1, pos});

            a[pos] = v;
            one[a[pos]].insert(pos);
            if (pos > 1)
                two[lca(a[pos - 1], a[pos])].insert({pos - 1, pos});
        }

        if (op == 2) {
            cin >> l >> r >> v;

            auto it = one[v].lower_bound(l);
            if (it != one[v].end() && *it <= r) {
                cout << *it << ' ' << *it << '\n';
                continue;
            }

            auto it2 = two[v].lower_bound({l, 0});
            if (it2 != two[v].end() && it2->se <= r) {
                cout << it2->fi << ' ' << it2->se << '\n';
                continue;
            }

            cout << "-1 -1\n";
        }
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...