Cod sursa(job #2017122)

Utilizator cipri321Marin Ciprian cipri321 Data 31 august 2017 12:41:42
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <vector>
#include <cstdio>
#define DIM 100001
using namespace std;
ifstream fi("lca.in");
FILE *fo;
int n,m;
int nre,E[2*DIM],L[2*DIM],H[DIM];
int VIZ[DIM];
vector<int> V[DIM];
int M[10*DIM];
void euler(int v,int l)
{
    VIZ[v]=1;
    nre++;
    E[nre]=v,L[nre]=l;
    if(!H[v]) H[v]=nre;
    for(int i=0;i<V[v].size();i++)
    {
        int to=V[v][i];
        if(!VIZ[to])
        {
            euler(to,l+1);
            nre++;
            E[nre]=v,L[nre]=l;
        }
    }
}
void init(int v,int l,int r)
{
    if(l==r)
        M[v]=l;
    else
    {
        init(2*v,l,(l+r)/2);
        init(2*v+1,(l+r)/2+1,r);
        if(L[M[2*v]]<=L[M[2*v+1]])
            M[v]=M[2*v];
        else
            M[v]=M[2*v+1];
    }
}
int query(int v,int st,int dr,int l,int r)
{
    if(st>r||dr<l)
        return -1;
    if(st>=l&&dr<=r)
        return M[v];
    int p1=query(2*v,st,(st+dr)/2,l,r);
    int p2=query(2*v+1,(st+dr)/2+1,dr,l,r);
    if(p1==-1)
        return p2;
    if(p2==-1)
        return p1;
    if(L[p1]<=L[p2])
        return p1;
    return p2;
}
int main()
{
    fo=fopen("lca.out","w");
    fi>>n>>m;
    for(int i=2;i<=n;i++)
    {
        int p;
        fi>>p;
        V[p].push_back(i);
        V[i].push_back(p);
    }
    euler(1,1);
    init(1,1,nre);
    for(int i=1;i<=m;i++)
    {
        int a,b;
        fi>>a>>b;
        fprintf(fo,"%d\n",E[query(1,1,nre,min(H[a],H[b]),max(H[a],H[b]))]);
    }
    fi.close();
    fclose(fo);
    return 0;
}