Cod sursa(job #3164878)

Utilizator razviii237Uzum Razvan razviii237 Data 4 noiembrie 2023 16:50:55
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <iostream>
#include <climits>
#include <string>
#include <vector>
#include <cstring>

using namespace std;

vector<int> child[100005];
int parent[100005];
vector<pair<int, int> >rep;
int lg[400005];
int first[100005];
pair<int, int> rmq[20][400005];
pair<int, int> best(pair<int, int> a, pair<int, int> b) {
    if(a.second < b.second)
        return a;
    return b;
}

void euler(int x, int depth) {
    if(first[x] == -1)
        first[x] = rep.size();
    rep.push_back({x, depth});
    for(auto u : child[x]) {
        euler(u, depth + 1);
        rep.push_back({x, depth});
    }
}
pair<int, int> query(int x, int y) {
    if(x > y) swap(x, y);
    int loga = lg[y-x+1];
    cout << "loga: " << loga << '\n';
    pair<int, int> ans = best(rmq[loga][x], rmq[loga][y - (1 << (loga)) + 1]);
    return ans;
}
int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m, i, x, j, y;
    cin >> n >> m;
    memset(first, -1, sizeof(first));
    for(i = 2; i <= n; i ++) {
        cin >> x;
        child[x].push_back(i);
        parent[i] = x;
    }
    euler(1, 0);
    for(i = 2; i <= rep.size(); i ++)
        lg[i] = lg[i/2] + 1;

    int reps = rep.size();
    for(j = 0; j < reps; j ++) {
        rmq[0][j] = rep[j];
    }
    for(i = 1; (1 << i) < reps; i ++) {
        for(j = 0; j + i - 1 < reps; j ++) {
            rmq[i][j] = best(rmq[i-1][j], rmq[i-1][j + (1 << (i-1))]);
        }
    }
//    for(auto u : rep)
//        cout << u.first << ' ';
    for(i = 1; i <= m; i ++) {
        cin >> x >> y;
        pair<int, int> ans = query(first[x], first[y]);
        cout << ans.first << '\n';
    }
    return 0;
}