Cod sursa(job #2170333)

Utilizator Vlad_lsc2008Lungu Vlad Vlad_lsc2008 Data 14 martie 2018 23:31:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

int t;
int n,q;
vector<int> m[100005];
pair<int,int> lin[200010];
int pozi[100005];
int log[200005];
int put[30];
int d[30][200005];
int nr;

int mini(int a,int b)
{
    if(lin[a].second<=lin[b].second) return a;
    else return b;
}

int liniarize(int nod,int nivel)
{
    nr++;
    if(pozi[nod]==0) pozi[nod]=nr;
    lin[nr]=make_pair(nod,nivel);
    for(vector<int>::iterator it=m[nod].begin();it!=m[nod].end();it++)
    {
        liniarize(*it,nivel+1);
        nr++; lin[nr]=make_pair(nod,nivel);
    }
}

int main()
{
    ifstream t1("lca.in");
    ofstream t2("lca.out");
    t1>>n>>q;

    int i,j;
    int sns,a,b;
    for(i=1;i<=n-1;i++)
    {
        t1>>sns;
        m[sns].push_back(i+1);
    }

    liniarize(1,0);

    for(i=2;i<=nr;i++) log[i]=log[i/2]+1;
    put[0]=1;
    for(i=1;i<=20;i++) put[i]=2*put[i-1];

    for(i=1;i<=2*n-1;i++) d[0][i]=i;
    for(i=1;i<=log[nr];i++)
    {
        for(j=1;j<=nr;j++)
        {
            if( j - put[i] >=0 )
                    d[i][j]= mini( d[i-1][j],d[i-1][j-put[i-1]] );
            else d[i][j]= d[i-1][j];
        }
    }

    int aux;
    for(;q;q--)
    {
        t1>>a>>b;
        a=pozi[a]; b=pozi[b];
        if( b < a)
        {
            aux = b;
            b=a;
            a=aux;
        }
        //cout<<a<<' '<<b<<'\n';
        t2<<lin [ mini( d[ log[b-a] ][ b ], d[ log[b-a] ][ a + put[ log[b-a] ] -1 ] ) ].first  <<'\n';
    }

    return 0;
}