Submission #1324560

#TimeUsernameProblemLanguageResultExecution timeMemory
1324560witek_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;
vi jaki_log;
vvi spt; //sparse table
vector<map<int, int>> tr; //drzewo przedzialowe ktore trzyma wystepowanie

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 lca(int u, int v) {
    if (pre[u] > pre[v]) swap (u, v);
    int l = jaki_log[kon[v] - poc[u] + 1];
    int mp = min(spt[l][poc[u]] ,spt[l][kon[v] - (1 << l) + 1]);
    return p_odw[mp];
}

void dod(int ind, int val) {
    ind += stala;
    while (ind) {
        tr[ind][val]++;
        ind /= 2;
    }
}

void usun(int ind, int val) {
    ind += stala;
    while (ind) {
        tr[ind][val]--;
        if (tr[ind][val] == 0) {
            tr[ind].erase(val);
        }
        ind /= 2;
    }
}

int il(int ind, int val) {
    if (tr[ind].find(val) == tr[ind].end()) return 0;
    return tr[ind][val];
}

int zcz(int l, int r, int val) {
    l += stala;
    r += stala;
    if (l > r) return 0;
    int wyn = 0;
    if (tr[l].find(val) != tr[l].end()) wyn += tr[l][val];
    if (l==r) return wyn;
    if (tr[r].find(val) != tr[r].end()) wyn += tr[r][val];
    while (r > (l + 1)) {
        if (!(l&1)) {
            wyn += il(l ^ 1, val);
        } 
        if (r&1) {
            wyn += il(r ^ 1, val);
        }
        r /= 2;
        l /= 2;
    }
    return wyn;
}

int kty(int v, int val, int k) {
    if (v >= stala) return (v - stala);
    int le = il(v * 2, val);
    if (le <= k) {
        return kty((v *2) + 1, val, k - le);
    } else {
        return kty(v * 2, val, k);
    }
}

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.clear();
    g = {}; //mniej pamieci
    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;
    }
    jaki_log.resize(sz(sc) + 1);
    jaki_log[0] = 0;
    jaki_log[1] = 0;
    int bit = 0;
    f(i, 2, sz(jaki_log)) {
        if (i == (1 << (bit + 1))) bit++;
        jaki_log[i] = bit;
    }
    spt.resize(bit + 1);
    spt[0].resize(sz(sc));
    f(i, 0, sz(sc)) spt[0][i] = pre[sc[i]];
    f(l, 1, bit + 1) {
        spt[l].resize(sz(sc) - (1 << l) + 1);
        f(i, 0, sz(sc) - (1 << l) + 1) {
            spt[l][i] = min(spt[l - 1][i], spt[l - 1][i + (1 << (l - 1))]);
        }
    }
    sc.clear();
    sc = {};
    vi a(m);
    f(i, 0, m) cin >> a[i];
    stala = 1;
    while ((2 *m - 1) > stala) stala *= 2;
    tr.resize(2 * (stala + 2));
    f(i, 0, 2 * m - 1) {
        if (i&1) {
            dod(i, lca(a[i/2], a[(i/2) + 1]));
        } else {
            dod(i, a[i/2]);
        }
    }
    
    rep(_, q) {
        int rd;
        cin >> rd;
        if (rd == 1) {
            int ind, val;
            cin >> ind >> val;
            ind--;
            usun(ind * 2, a[ind]);
            int sv = a[ind]; //stara val
            a[ind] = val;
            dod(ind * 2, a[ind]);
            if (ind) {
                usun(ind * 2 - 1, lca(sv, a[ind - 1]));
                dod(ind - 1, lca(a[ind], a[ind - 1]));
            }
            if (ind < (2 * (m - 1))) {
                usun(ind * 2 + 1, lca(sv, a[ind + 1]));
                dod(ind * 2 + 1, lca(a[ind], a[ind + 1]));
            }
        } else {
            int l, r, v;
            cin >> l >> r >> v;
            l--;
            r--;
            l *= 2;
            r *= 2;
            int s1 = zcz(0, l - 1, v);
            int s2 = zcz(l, r, v);
            if (s2 == 0) {
                cout << -1 << " " << -1 << en;
                continue;
            }
            int ind = kty(1, v, s1);
            int ni = (ind/2) + 1;
            if (ind&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...