Cod sursa(job #1975435)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 30 aprilie 2017 21:58:57
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <cstdio>
#include <vector>
#define pb push_back
using namespace std;
const int DIM=50000,nmax=100004,lmax=18;
char buff[DIM];
int poz=DIM-1;
void citeste(int &nr)
{
    nr=0;
    while(!('0'<=buff[poz]&&buff[poz]<='9'))
    {
        if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
    }
    while('0'<=buff[poz]&&buff[poz]<='9')
    {
        nr=nr*10 + buff[poz]-'0';
        if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
    }
}
int lvl[nmax],t[lmax][nmax];
vector<int>adj[nmax];
int n,m;
inline void citire()
{
    citeste(n),citeste(m);
    for(int i=1;i<n;i++)
    {
        citeste(t[0][i+1]);
        adj[t[0][i+1]].pb(i+1);
    }
}
void define_lvl(int nod)
{
    for(vector<int>::iterator it=adj[nod].begin();it!=adj[nod].end();++it)
    {
        if(lvl[*it]==0)
        {
            lvl[*it]=lvl[nod]+1;
            define_lvl(*it);
        }
    }
}
int dad(int nod,int val)
{
    //printf("%d\n",(1<<1));
    for(int i=17;i>=0;--i)
    {
        if(val&(1<<i)) nod=t[i][nod];
    }
    return nod;
}
int lca(int n1,int n2)
{
    if(lvl[n1]>lvl[n2]) swap(n1,n2);
    if(lvl[n1]!=lvl[n2]) n2=dad(n2,lvl[n2]-lvl[n1]);
   //printf("%d %d\n",n1,n2);
    if(n1==n2) return n1;
    int rasp=n1;
    for(int i=17;i>=0;--i)
    {
        if(t[i][n1]!=t[i][n2]&&t[i][n1]!=0&&t[i][n2]!=0)
        {
            rasp=t[i][n1];
            n1=t[i][n1];
            n2=t[i][n2];
        }
    }
    return t[0][rasp];
}
inline void define_t()
{
    for(int i=1;i<=17;i++)
    {
        for(int j=1;j<=n;j++) t[i][j]=t[i-1][t[i-1][j]];
    }
}
inline void solve()
{
    for(;m>0;--m)
    {
        int n1,n2;
        citeste(n1),citeste(n2);
        printf("%d\n",lca(n1,n2));
    }
}
int main()
{
    freopen ("lca.in","r",stdin);
    freopen ("lca.out","w",stdout);
    citire();
    lvl[1]=1;
    define_lvl(1);
    //for(int i=1;i<=n;i++) printf("%d ",lvl[i]);
   // printf("\n");
    define_t();
    solve();
}