Cod sursa(job #1060831)

Utilizator classiusCobuz Andrei classius Data 18 decembrie 2013 20:08:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
using namespace std;

#include<ios>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<utility>
#include<cstdio>
#include<cstdlib>
#include<cassert>
#include<numeric>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<deque>

#define FILES


#ifdef FILES
#include<fstream>
ifstream cin("lca.in");
ofstream cout("lca.out");
#else
#include<iostream>
#endif

#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define ALL(a) a.begin(),a.end()
#define p_b(a) push_back(a)
#define m_p(a,b) make_pair(a,b)
#define p_p(a,b) p_b(m_p(a,b))

typedef unsigned char uchar;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef queue<int> qint;
typedef pair<int,int> pii;
typedef vector<pii> vpii;
typedef vector<string> vstr;
typedef queue<int> qint;
typedef deque<int> dqint;
typedef deque<ll> dqll;
typedef map<string,int> mpstri;
typedef map<int,int> mpinti;
typedef map<string,string> mpstrs;
typedef map<string,vstr> mpstrvs;
const int INFI=(1<<30);
const ll INFL=(1LL<<62);

int fh[100001],lv[100001];
int lc[20][100001];
vint v[100001];
int mxh;

void dfs(int i,int h){
    mxh=max(mxh,h);

    lv[i]=h;
    for(uint j=0;j<v[i].size();j++){
        int ds=v[i][j];
        if(!lv[ds])
            dfs(ds,h+1);
    }
}

void build_lca(int n){
    for(int i=1;i<=n;i++)
        lc[0][i]=fh[i];

    for(int j=1;(1<<j)<=mxh;j++)
        for(int i=1;i<=n;i++)
            lc[j][i]=lc[j-1][lc[j-1][i]];
}

int lca(int x,int y){
    if(lv[x]>lv[y]){
        int ax=lv[x]-lv[y];
        for(int j=0;(1<<j)<=ax;j++)
            if(ax & (1<<j))
                x=lc[j][x];
    }
    if(lv[y]>lv[x]){
        int ax=lv[y]-lv[x];
        for(int j=0;(1<<j)<=ax;j++)
            if(ax & (1<<j))
                y=lc[j][y];
    }

    while(true){
        int j=0;
        while(lc[j][x]!=lc[j][y]) j++;
        if(!j) break;
        j--;
        x=lc[j][x];
        y=lc[j][y];
    }

    return (x!=y ? lc[0][x] : x);
}


int main(){
    int n,m;
    cin>>n>>m;

    fh[1]=1;
    for(int i=2;i<=n;i++){
        int x;
        cin>>x;
        fh[i]=x;
        v[x].p_b(i);
    }
    dfs(1,1);

    build_lca(n);

    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        cout<<lca(x,y)<<'\n';
    }

    return 0;
}