Cod sursa(job #3143531)

Utilizator SerbanCaroleSerban Carole SerbanCarole Data 31 iulie 2023 11:28:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <algorithm>
#define pb push_back
using namespace std;
using pii = pair<int,int>;

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

//lca cu carare grea

const int MAX = 1e5 + 1;

int n , q , depth[MAX], nrd[MAX] , f[MAX] , x , t[MAX] , wo[MAX];
bitset <MAX> viz;
vector <int> st;
vector <int> g[MAX];

void dfs( int x , int p ){

    t[x] = p;
    depth[x] = depth[p]+1;
    for(auto it : g[x]){

        if(it == p) continue;
        dfs(it,x);
        nrd[x]+=nrd[it];
    }
    nrd[x]++;
    int hm = 0;
    for(auto it : g[x]){

        if(it == p) continue;
        if(nrd[it] >= nrd[x]/2) hm++;
    }

    if(!hm) st.pb(x);
}

int main(){

    cin >> n >> q;

    for(int i = 2 ; i <= n ; i++){

        cin >> x;
        g[x].pb(i);
        g[i].pb(x);
    }

    dfs(1,0);

    int hn = 0;

    for(auto it : st){

        hn++;

        while(it > 0 && !viz[it] && nrd[it] >= nrd[t[it]]/2){
            viz[it] = 1;
            wo[it] = hn;
            f[hn] = it;
            it = t[it];
        }

        if(it!=0 && !viz[it]){
            viz[it] = 1;
            wo[it] = hn;
            f[hn] = it;
        }
    }

    int a , b;

    while(q--){

        cin >> a >> b;

        vector <int> first;
        vector <int> second;

        int ca = a , cb = b;

        while(a){

            first.pb(wo[a]);
            a = t[f[wo[a]]];
        }

        while(b){

            second.pb(wo[b]);
            b = t[f[wo[b]]];
        }

        int sz = min(first.size(),second.size());
        reverse(first.begin(),first.end());
        reverse(second.begin(),second.end());
        int asta = 0;

        for(int i = 0 ; i < sz ; i++){

            if(first[i]==second[i]) asta = first[i];
            else break;
        }

        a = ca;
        b = cb;

        while(wo[a]!=asta){

            a = t[f[wo[a]]];
        }

        while(wo[b]!=asta){

            b = t[f[wo[b]]];
        }

        if(depth[a] < depth[b]){

            cout << a << '\n';

        }else cout << b << '\n';
    }

    return 0;
}