Cod sursa(job #2315394)

Utilizator aturcsaTurcsa Alexandru aturcsa Data 9 ianuarie 2019 21:38:56
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <ctype.h>

using namespace std;

int k,p;
ifstream fi("lca.in");
ofstream fo("lca.out");
vector <int> D[100001];
int n,q;
int ne,E[500001];
int FIRST[100001];
int LEVEL[100001];
int T[500001][20];

int query(int st, int dr)
/// returneaza varful de nivel minim care apare
/// intre E[st] si E[dr];
{
    if (st>dr)
        swap(st,dr);
    int rez;
    rez=E[st];
    for (int i=k;i>=0;i--)
        if (st+(1<<i)-1<=dr)
        {
            if (LEVEL[rez]>LEVEL[T[st][i]])
                rez=T[st][i];
            st=st+(1<<i);
        }
    return rez;
}

void lvl(int nod,int level)
{
    LEVEL[nod]=level;
    vector <int> :: iterator it;
    for (it=D[nod].begin(); it!=D[nod].end(); it++)
        lvl(*it,level+1);
}

void euler(int nod)
{
    vector <int> :: iterator it;
    if (D[nod].size()==0)
    {
        ne++;
        E[ne]=nod;
        if(FIRST[nod]==0)
            FIRST[nod]=ne;
    }
    else
    {
        ne++;
        E[ne]=nod;
        if(FIRST[nod]==0)
            FIRST[nod]=ne;
        for (it=D[nod].begin(); it!=D[nod].end(); it++)
        {
            euler(*it);
            ne++;
            E[ne]=nod;
            if(FIRST[nod]==0)
                FIRST[nod]=ne;
        }
    }

}




int main()
{
    fi>>n>>q;
    for(int i=2; i<=n; i++)
    {
        int a;
        fi>>a;
        D[a].push_back(i);
    }
    euler(1);
    lvl(1,0);
    /// se construieste sparse table pentru E
    /// k este indicele ultimei coloane din T
    k=0;
    p=1;
    while (p*2<=ne)
    {
        k++;
        p=p*2;
    }
    /// se construieste sparse table
    for (int i=1; i<=ne; i++)
        T[i][0]=E[i];
    for (int j=1; j<=k; j++)
        for (int i=1; i<=ne-(1<<j)+1; i++)
            if (LEVEL[T[i][j-1]]<LEVEL[T[i+(1<<(j-1))][j-1]])
                T[i][j]=T[i][j-1];
            else
                T[i][j]=T[i+(1<<(j-1))][j-1];
    /// se raspunde la intrebari
    for (int qu=1; qu<=q; qu++)
    {
        int a,b;
        fi>>a>>b;
        fo<<query(FIRST[a],FIRST[b])<<"\n";
    }
    fo.close();
    return 0;
}