Cod sursa(job #2099912)

Utilizator Alex18maiAlex Enache Alex18mai Data 4 ianuarie 2018 20:24:16
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream cin ("lca.in");
ofstream cout ("lca.out");

vector < vector < int > > gr(100100);
vector < int > dad (100100);
vector < int > G (100100);
vector < int > lv (100100);

int rad = 0;

int cont = 0;
vector < vector < int > > chain(100100);
vector < int > CHAIN(100100);
vector < int > NR(100100);
vector < int > LV(100100);

void dfs (int root){

    lv[root] = lv[dad[root]] + 1;

    int MAX = 0;
    int go = 0;
    G[root] = 1;

    for (auto &x : gr[root]){
        dfs(x);
        if (chain[CHAIN[x]].size() < rad && MAX < G[x]){
            MAX = G[x];
            go = x;
        }
        G[root] += G[x];
    }

    if (go == 0){
        cont ++;
        chain[cont].push_back(root);
        CHAIN[root] = cont;
        NR[root] = 0;
        LV[cont] = lv[root];
    }
    else{
        chain[CHAIN[go]].push_back(root);
        CHAIN[root] = CHAIN[go];
        NR[root] = chain[CHAIN[root]].size() - 1;
        LV[CHAIN[root]] = lv[root];
    }

}

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    //bucati de radical (HPD in mizerie)

    int n , m;
    cin>>n>>m;

    rad = int(sqrt(n));

    for (int i=2; i<=n; i++){
        cin>>dad[i];
        gr[dad[i]].push_back(i);
    }

    dfs(1);

    /*cout<<cont<<'\n';
    for (int i=1; i<=cont; i++){
        for (auto &x : chain[i]){
            cout<<x<<" ";
        }
        cout<<'\n';
    }
    cout<<'\n';*/

    for (int i=1; i<=m; i++){
        int x , y;
        cin>>x>>y;

        while (CHAIN[x] != CHAIN[y]){
            if (LV[CHAIN[x]] > LV[CHAIN[y]]){
                x = dad[chain[CHAIN[x]][chain[CHAIN[x]].size() - 1]];
            }
            else{
                y = dad[chain[CHAIN[y]][chain[CHAIN[y]].size() - 1]];
            }
        }

        if (NR[x] > NR[y]){
            cout<<x<<'\n';
        }
        else{
            cout<<y<<'\n';
        }

    }

    return 0;
}