Cod sursa(job #1962400)

Utilizator Lungu007Lungu Ionut Lungu007 Data 11 aprilie 2017 18:54:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <utility>
#define NMAX 100005
#define LOG 22

using namespace std;

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

int t[NMAX],h[NMAX],first[NMAX],v[2*NMAX],viz[NMAX];
pair<int,int> d[LOG][2*NMAX];
vector<int> a[NMAX];
int n,m,x,y;

int log(int n)
{
    int i;
    for(i=0;(1<<i)<=n;i++);

    return i;
}

int lca(int x,int y)
{
    x = first[x];
    y = first[y];
    if(x>y) swap(x,y);
    int lg = log(y-x+1)-1;
   // cout <<x << " " <<y << endl;

    //pair<int,int> p = min(d[lg][x].first,d[lg][y+1-(1<<lg)].first);

    if(d[lg][x].first <= d[lg][y+1-(1<<lg)].first)
    {
        return d[lg][x].second;
    }

    return d[lg][y+1-(1<<lg)].second;
}

int contor = 1;
int depth = 1;

void dfs(int nod)
{
    h[nod] = depth;
    v[contor++] = nod;
    for(int i=0;i<a[nod].size();i++)
    {

        if(!viz[a[nod][i]])
        {
            viz[a[nod][i]]=1;
            depth++;
            dfs(a[nod][i]);
            depth--;
             v[contor++] = nod;
        }
       // v[contor++] = nod;

    }

}

void rmq()
{
    int lgn = log(n);
    for(int i=1;i<=2*n-1;i++)
    {
        d[0][i].first = h[v[i]];
        d[0][i].second = v[i];
    }

    for(int i=1;i<=lgn;i++)
    {
        for(int j=1;j<=2*n-1-(1<<i);j++)
        {
            d[i][j] = min(d[i-1][j],d[i-1][j+(1<<(i-1))]);
        }
    }

}

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

    viz[1]=1;
    dfs(1);
    for(int i=1;i<2*n;i++)
    {
        if(first[v[i]]==0)
        {
            first[v[i]] = i;
        }
    }

    rmq();
    //cout << lca(784,53189);
    for(int i=0;i<m;i++)
    {
        in >> x >> y;
        out << lca(x,y) << '\n';
    }
    return 0;
}