제출 #1324567

#제출 시각아이디문제언어결과실행 시간메모리
1324567witek_cppBirthday gift (IZhO18_treearray)C++20
0 / 100
1 ms332 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

#define st first
#define nd second
#define pb push_back
#define all(a) a.begin(), a.end()
#define sz(a) int(a.size())
#define f(i, a, b) for (int i = a; i < b; i++)
#define rep(i, a) f(i, 0, a)
//#define int ll
#define tv(a, x) for (auto& a : x)
#define DUZO 1000000000000000000LL
#define en "\n"
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vii = vector<pii>;

int t = 0;
int stala = 1;

vvi g;
vi sc;
vi pre;
vi p_odw;
vi poc;
vi kon;
vector<set<int>> wstp; //wystapienia
vi tr; //drzewo ktore bedzie odpowiadac na lca 

void dfs(int v, int p) {
    pre[v] = t;
    p_odw[t] = v;
    t++;
    sc.pb(v);
    tv(u, g[v]) {
        if (u == p) continue;
        dfs(u, v);
        sc.pb(v);
    }
}

int zcz(int l, int r) {
    l += stala;
    r += stala;
    int wyn = min(tr[l], tr[r]);
    while (r > (l + 1)) {
        if (!(l&1)) {
            wyn = min(wyn, tr[l ^ 1]);
        } else {
            wyn = min(wyn, tr[r ^ 1]);
        }
        r /= 2;
        l /= 2;
    }
    return wyn;
}

int lca(int u, int v) {
    if (pre[u] > pre[v]) swap (u, v);
    return p_odw[zcz(poc[u], kon[v])];
}

void solve() {
    int n, m, q;
    cin >> n >> m >> q;
    g.resize(n + 1);
    rep(_, n - 1) {
        int u, v;
        cin >> u >> v;
        g[u].pb(v);
        g[v].pb(u);
    }
    pre.resize(n + 1);
    p_odw.resize(n + 1);
    dfs(1, 0);
    g = {};
    g.clear();
    poc.resize(n + 1, -1);
    kon.resize(n + 1);
    f(i, 0, sz(sc)) {
        if (poc[sc[i]] == -1) poc[sc[i]] = i;
        kon[sc[i]] = i;
    }

    stala = 1;
    while (sz(sc) > stala) stala *= 2;
    tr.resize(2 * (stala + 2), 10 * n);
    f(i, 0, sz(sc)) {
        tr[i + stala] = pre[sc[i]];
    }
    for (int i = stala - 1; i; i--) {
        tr[i] = min(tr[i * 2], tr[(i * 2) + 1]);
    }

    vi a(m);
    f(i, 0, m) cin >> a[i];
    vi tab(2 * m - 1); //prawdziwa tablica ktora trzyma co tak naprawde jest
    f(i, 0, 2 * m - 1) {
        if (i&1) {
            tab[i] = lca(a[(i/2)], a[(i/2) + 1]);
        } else {
            tab[i] = a[(i/2)];
        }
    }

    wstp.resize(n + 1);
    f(i, 0, sz(tab)) {
        wstp[tab[i]].insert(i);
    }
    
    rep(_, q) {
        int rd;
        cin >> rd;
        if (rd == 1) {
            int ind, val;
            cin >> ind >> val;
            ind--;
            ind = ind * 2; //ind w nowej tablicy ig
            wstp[tab[ind]].erase(ind);
            tab[ind] = val;
            wstp[val].insert(ind);
            if (ind) {
                wstp[tab[ind - 1]].erase(ind - 1);
                int lc = lca(tab[ind], tab[ind - 2]);
                tab[ind - 1] = lc;
                wstp[tab[ind - 1]].insert(ind - 1);
            }
            if (ind < (2 * (m - 1))) {
                wstp[tab[ind + 1]].erase(ind + 1);
                int lc = lca(tab[ind], tab[ind + 2]);
                tab[ind + 1] = lc;
                wstp[tab[ind + 1]].insert(ind + 1);
            }
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            l--;
            r--;
            l *= 2;
            r *= 2;
            auto it = wstp[v].lower_bound(l);
            if (it == wstp[v].end()) {
                cout << -1 << " " << -1 << en;
                continue;
            }
            int val = *it;
            if (val > r) {
                cout << -1 << " " << -1 << en;
                continue;
            }
            int ni = (val/2) + 1;
            if (val&1) {
                cout << ni << " " << ni + 1 << en;
            } else {
                cout << ni << " " << ni << en;
            }
        }
    }
}

int32_t main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int q = 1;
    //cin >> q;
    while (q--) {
        solve();
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...