Cod sursa(job #2829430)

Utilizator OrzaSERBANSerban Orza OrzaSERBAN Data 8 ianuarie 2022 16:48:38
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <bits/stdc++.h>

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

int n,m,nr;
struct lca
{
    int t,h;
    vector<int> fii;
}v[100001];
int eu[200005];
int h[200005];
int a[100001];//prima aparitie a lui i;
int minim[100001][19];
void nodStDr(int k,int val)
{
    int z=v[k].fii.size(),i;
    nr++;
    v[k].h=val;
    a[k]=nr;
    eu[nr]=k;
    h[nr]=val;
    for(i=0;i<z;i++)
    {
        nodStDr(v[k].fii[i],val+1);
        nr++;
        eu[nr]=k;
        h[nr]=val;
    }
}
void minime()//minim[i][j] este pozitia elementului minim in poz[]
{
    int i,j,x,y;
    for(i=0;i<=nr;i++)
        minim[i][0]=i;
    for(j=1;(1<<j)<=nr;j++)
        for(i=0;i<=nr;i++)
        {
            x=minim[i][j-1];
            y=minim[i+(1<<(j-1))][j-1];
            if(eu[x]<=eu[y])
                minim[i][j]=x;
            else
                minim[i][j]=y;
        }
}
int getMinim(int st,int dr)
{
    if(st>dr)
        swap(st,dr);
    int k,i;
    k=log2(dr-st+1);
    int x=minim[st][k];
    int y=minim[dr-(1<<k)+1][k];
    if(eu[x]<=eu[y])
        return x;
    return y;
}
int main()
{
    int i,j,x,y,z;
    f>>n>>m;
    for(i=2;i<=n;i++)
    {
        f>>v[i].t;
        v[v[i].t].fii.push_back(i);
    }
    nodStDr(1,0);
    minime();
    for(i=1;i<=m;i++)
    {
        f>>x>>y;
        //raspunsul este nodul cu h cel mai mic din secventa [x si y] din vectorul parcurgerii euler  (nod,st,dr)
        //cautam intre a[x] si a[y]
        g<<eu[getMinim(a[x],a[y])]<<'\n';

    }
    return 0;
}