Cod sursa(job #2703499)

Utilizator doru.nituNitu Doru Constantin doru.nitu Data 8 februarie 2021 17:22:39
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;

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

vector<int> a[100100];
int u[100100][20];
int depth[100100];

int n,m,l,d;

void dfs(int x, int p)
{
    d++;
    depth[x] = d; 
    u[x][0] = p;
    for(int i=1; i<=l; ++i)
    {
        u[x][i] = u[u[x][i-1]][i-1];
    }

    for(int i=0; i<a[x].size(); ++i)
    {
        int f = a[x][i];
        if(f != p)
        {
            dfs(f,x);
        }
    }

    d--;
}

int lca(int x, int y)
{
    // x va tine mereu adancimea mai mare
    if(depth[x] < depth[y])
        swap(x,y);

    // gasim stramosul lui x de pe adancime lui y
    if(depth[x] != depth[y])
    {
        for(int p = l; p>=0; --p)
        {
            int st = u[x][p];
            if(depth[st]>depth[y])
                x = u[x][p];
        }

        x = u[x][0];
    }

    if(x == y)
        return x;

    //g<<x<<" "<<y<<"    ";

    for(int p = l; p>=0; --p)
    {
        int stx = u[x][p];
        int sty = u[y][p];

        if(stx != sty)
        {
            x = stx;
            y = sty;
        }
    }

    return u[x][0];

}

int main()
{
    f>>n>>m;
    for(int i =2; i<=n; ++i)
    {
        int t;
        f>>t;
        a[t].push_back(i);
    }


    int p =1;
    l =0;
    while(p<=n)
    {
        p = p*2;
        l++;
    }
    
    d = 0;
    dfs(1, 1);
    
   /* for(int i =1; i<=n; ++i)
    {
        for(int j = 0; j<=l; ++j)
        {
            g<<u[i][j]<<" ";
        }
        g<<"     "<<depth[i];
        g<<"\n";
    }*/

    for(int i  =1; i<=m; ++i)
    {
        int x,y;
        f>>x>>y;
        int k = lca(x,y);
        g<<k<<"\n";
    }        

    return 0;
}