Cod sursa(job #2322852)

Utilizator CodrinsahCotarlan Codrin Codrinsah Data 18 ianuarie 2019 15:02:07
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.85 kb
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fi ("lca.in");
ofstream fo ("lca.out");
queue<int> q;
vector<int> v[100005];
int cod[100005],nivel[100005],sir[500005],reprez[100005],loc[100005],mat[100005][20];
int lgsir,nrnod,nrdrum;
void bfs()
{
    int codmax=0;
    q.push(1);
    while (!q.empty())
    {
        int nod=q.front();
        codmax++;cod[nod]=codmax;
        q.pop();
        for (int i=0;i<v[nod].size();i++)
        {
            int nextnod=v[nod][i];
            q.push(nextnod);
            nivel[nextnod]=nivel[nod]+1;
        }
    }
}
void dfs(int nod)
{
    lgsir++;
    sir[lgsir]=nod;
    for (int i=0;i<v[nod].size();i++)
    {
        int nextnod=v[nod][i];
        dfs(nextnod);
        lgsir++;
        sir[lgsir]=nod;
    }
}
void precalc()
{
    for (int i=1;i<=lgsir;i++)
    {
        mat[i][0]=cod[sir[i]];
        if (loc[cod[sir[i]]]==0) loc[cod[sir[i]]]=i;
    }
    for (int bit=1;(1<<bit)<=lgsir;bit++)
        for (int i=1;i+(1<<bit)-1<=lgsir;i++)
        mat[i][bit]=min(mat[i][bit-1],mat[i+(1<<(bit-1))][bit-1]);
}
int lca(int codnod1,int codnod2)
{
    if (codnod1==codnod2) return codnod1;
    int loc1=loc[codnod1],loc2=loc[codnod2];
    if (loc2<loc1) swap (loc1,loc2);
    int d=loc2-loc1;
    int lgmax=0;
    while (d>0) {lgmax++;d=d/2;}
    lgmax--;
    return min(mat[loc1][lgmax],mat[loc2-(1<<lgmax)+1][lgmax]);
}
int main()
{
    fi>>nrnod>>nrdrum;
    for (int i=2;i<=nrnod;i++)
    {
        int x;
        fi>>x;
        v[x].push_back(i);
    }
    bfs();
    dfs(1);
    for (int nod=1;nod<=nrnod;nod++)
        reprez[cod[nod]]=nod;
    precalc();
    for (int i=1;i<=nrdrum;i++)
    {
        int x,y;
        fi>>x>>y;
        int sol=reprez[lca(cod[x],cod[y])];
        fo<<sol<<'\n';
    }
    return 0;
}