Cod sursa(job #3175825)

Utilizator andiRTanasescu Andrei-Rares andiR Data 26 noiembrie 2023 13:57:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <iostream>
#include <fstream>
#include <vector>

#pragma GCC optimize("O3")

#define pb push_back
using namespace std;
ifstream fin("lca.in");
ofstream fout ("lca.out");
typedef pair<int, int> pii;

const int Nmax=1e5+5, Mmax=2e6+5;

struct DSU{
    vector<int> rep, s;
    DSU(int n){
        rep.resize(n);
        s.resize(n);
        for(int i = 0; i < n; i++){
            rep[i] = i;
            s[i] = 1;
        }
    }
    int get_rep(int nod){
        if (rep[nod]==nod)
            return nod;
        return rep[nod] = get_rep(rep[nod]);
    }
    void join(int a, int b){
        int ra=get_rep(a);
        int rb=get_rep(b);
        if (ra==rb)
            return;
        if (s[ra]<s[rb])
            swap(ra, rb);
        rep[rb]=ra;
        s[ra]+=s[rb];
    }
};

int n, m, sol[Mmax], rep[Nmax];
bool vis[Nmax];
vector <int> ad[Nmax];
vector <pii> querry[Nmax];

void dfs(int nod, int p, DSU &dsu){
    rep[nod]=nod;
    for (auto it:ad[nod])
        if (it!=p){
            dfs(it, nod, dsu);
            dsu.join(nod, it);
            rep[dsu.get_rep(it)]=nod;
        }
    vis[nod]=1;
    for (auto it:querry[nod])
        if (vis[it.first])
            sol[it.second]=rep[dsu.get_rep(it.first)];
}

int main(){
    fin>>n>>m;

    int nr;
    for (int i=1; i<n; i++){
        fin>>nr; nr--;
        ad[i].pb(nr);
        ad[nr].pb(i);
    }
    int a, b;
    for (int i=0; i<m; i++){
        fin>>a>>b; 
        a--; b--;

        querry[a].pb({b, i});
        querry[b].pb({a, i});
    }
    DSU dsu(n);
    dfs(0, -1, dsu);

    for (int i=0; i<m; i++)
        fout<<sol[i]+1<<'\n';
    return 0;
}