Cod sursa(job #2196978)

Utilizator vladboss2323Ciorica Vlad vladboss2323 Data 20 aprilie 2018 20:01:06
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

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

const int N=100005;

int n,rmq[21][2*N],q,timp,e[2*N],nr,nivel[N],upoz[N],log[2*N];
bool viz[N];
vector <int> a[N];

void citire()
{
    in>>n>>q;
    for(int i=2; i<=n; i++)
    {
        int x;
        in>>x;
        a[x].push_back(i);
    }
}

void precalculare()
{
    int i;
    log[1]=0;
    for(i=2; i<=2*n; i++)
        log[i]=log[i/2]+1;
}

void dfs(int nod)
{
    int i,vecin;
    e[++nr] = nod;
    viz[nod]=1;
    for(i=0; i<a[nod].size(); i++)
    {
        vecin=a[nod][i];
        if(!viz[vecin])
        {
            nivel[vecin]=nivel[nod]+1;
            dfs(vecin);
            e[++nr] = nod;
        }
    }
}

void RMQ()
{
    int i,j;
    for(i=1; i<=2*n; i++)
        rmq[0][i]=e[i];
    for(i=1; 1<<i <= n ; i ++)
        for(j=(1<<i); j<=2*n; j++)
        {
            if (nivel[rmq[i-1][j]] < nivel[rmq[i-1][j-(1<<(i-1))]])
            {
                rmq[i][j] = rmq[i-1][j];
            }
            else
            {
                rmq[i][j] = rmq[i-1][j-(1<<(i-1))];
            }
        }
}

void lca(int x,int y)
{
    x = upoz[x];
    y = upoz[y];
    if(x>y)
        swap(x,y);
    int l=log[y-x+1];
    if(nivel[rmq[l][y]] < nivel[rmq[l][x+(1<<l)-1]])
    {
        if(rmq[l][y]!=0)
            out<<rmq[l][y]<<'\n';
        else
            out<<1<<'\n';
        //out<<l<<" "<<y<<endl;
    }
    else
    {
        if(rmq[l][x+(1<<l)-1]!=0)
            out<<rmq[l][x+(1<<l)-1]<<'\n';
        else
            out<<1<<'\n';
        //out<<l<<" "<<x+(1<<l)-1<<endl;
    }
}
void raspuns()
{
    while(q--)
    {
        int x,y;
        in>>x>>y;
        lca(x,y);

    }
}
int main()
{
    int i,j;
    citire();
    precalculare();
    dfs(1);
    /*
    for(i=1; i<=n; i++)
        out<<log[i]<<" ";
    out<<endl;
    for(i=1; i<=nr; i++)
        out<<e[i]<<" ";
    out<<endl;
    */
    for(i=1; i<=nr; i++)
    {
        upoz[e[i]]=i;
    }
    /*for(i=1; i<=n; i++)
        out<<upoz[i]<<" ";
    out<<endl;
    for(i=1; i<=n; i++)
        out<<nivel[i]<<" ";
    out<<endl;
    */
    RMQ();
    /* for(i=0; 1<<i <=n ; i++)
     {
         for(j=1; j<=2*n; j++)
             out<<rmq[i][j]<<" ";
         out<<endl;
     }
     */
    raspuns();
    return 0;
}