Cod sursa(job #2723097)

Utilizator razviii237Uzum Razvan razviii237 Data 13 martie 2021 15:48:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
//lca cu rmq

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int maxn = 400005;
struct xy { int x, y; };
bool operator > (xy a, xy b) {
    return a.y > b.y;
}
bool operator < (xy a, xy b) {
    return a.y < b.y;
}
xy a[maxn];
int k;
vector <int> v[maxn];
int first[maxn];
xy d[20][maxn];

xy mn(xy a, xy b) {
    return (a < b ? a : b);
}

void dfs(int x, int niv) {
    a[++k] = {x, niv};
    if(first[x] == 0) {
        first[x] = k;
    }
    for(auto u : v[x]) {
        dfs(u, niv + 1);
        a[++k] = {x, niv};
    }
}

int lg[maxn];
int query(int x, int y) {
    int loga = lg[y - x + 1];
    xy ans = mn( d[loga][x], d[loga][y - (1 << loga) + 1] );
    return ans.x;
}

int main()
{
    int n, t, i, x, y, j, h;

    f >> n >> t;
    for(i = 2; i <= n; i ++) {
        f >> x;
        v[x].push_back(i);
    }
    dfs(1, 0);
    for(i = 1; i <= k; i ++) {
        d[0][i] = a[i];
    }

    x = 0;
    for(i = 1; i <= k; i ++) {
        if((1 << (x + 1)) == i) {
            x ++;
        }
        lg[i] = x;
    }

    for(i = 1; i <= 20; i ++) {
        for(j = 1; j + (1 << i) - 1 <= k; j ++) {
            d[i][j] = mn(d[i-1][j], d[i-1][j + (1 << (i - 1))]);
        }
    }

    while(t --) {
        f >> x >> y;
        x = first[x];
        y = first[y];
        if(x > y) { swap(x, y); }
        g << query(x, y) << '\n';
    }

    f.close(); g.close();
    return 0;
}