Cod sursa(job #2680844)

Utilizator BereaBerendea Andrei Berea Data 4 decembrie 2020 15:30:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
//#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
const int maxn=2e5+5;
int n,i,c=1,m,x,y,pow;
int radacina;
int v[maxn],e[maxn],nivel[maxn],f[maxn],l[maxn];
int rmq[21][maxn];
int fiu[maxn];
bool viz[maxn];
vector<int>g[maxn];

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

void dfs(int x)
{
    e[c++]=x;
    f[x]=c-1;
    for (auto y:g[x])
    {
        if (viz[y]==false)
        {
            viz[y]=true;
            nivel[y]=nivel[x]+1;
            dfs(y);
            e[c++]=x;
        }
    }
}

void Rmq()
{
    for (i=2;i<=2*n;i++) l[i]=l[i/2]+1;
    for (i=1;i<=2*n;i++) rmq[0][i]=e[i];
    for (int pow=1;pow<=20;pow++)
    {
        for (i=1;i<=2*n-(1<<pow)+1;i++)         // merge de la primu element pana la 2*n - puterea de 2
        {
            if (nivel[rmq[pow-1][i]] < nivel[rmq[pow-1][i+(1<<(pow-1))]]) rmq[pow][i]=rmq[pow-1][i];
            else rmq[pow][i]=rmq[pow-1][i+(1<<(pow-1))];
        }
    }
}

int lca(int x,int y)
{
    x=f[x];
    y=f[y];
    if (y<x) swap(x,y);
    pow=l[y-x+1];
    if (nivel[rmq[pow][x]]<nivel[rmq[pow][y-(1<<pow)+1]]) return rmq[pow][x];
    else return rmq[pow][y-(1<<pow)+1];
}

int main()
{
    cin>>n>>m;
    /*//for (i=1;i<=n;i++) cin>>v[i];
    for (i=1;i<n;i++)
    {
        cin>>x>>y;
        g[x].push_back(y);
    }*/
    for (i=2;i<=n;i++)
    {
        cin>>x;
        g[x].push_back(i);
    }
    /*for ( int i =1 ; i <= n; ++i)
	if(fiu[i] == 0) {
radacina = i;
break;
}*/

    dfs(1);
    Rmq();
    pair<int,int>idk;
    pair<int,int>cast;
    int maxi=0;
    for (i=1;i<=m;i++)
    {
        cin>>idk.first>>idk.second;
        int aaa=lca(idk.first,idk.second);
        /*if (v[aaa]>maxi)
        {
            maxi=v[aaa];
            cast=idk;
        }
        else if (v[aaa]==maxi) if (idk<cast) cast=idk;*/
        cout<<aaa<<"\n";
    }
    //cout<<maxi<<" "<<cast.first<<" "<<cast.second;
}