Cod sursa(job #1184938)

Utilizator ArchazeyBaltatu Andrei-Mircea Archazey Data 14 mai 2014 17:57:33
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.31 kb
#include<fstream>
#include<vector>
#include<bitset>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n,m,a[100005],Euler[200005],lg,nivel[200005],puteri[25],logaritm[200005];
int mat[200005][20],aparitii[100005];
vector<int>v[100005];
bitset<100005>viz;

inline void DFS(int x,int niv)
{
    int i,len;
    nivel[x]=niv;
    len=v[x].size();
    for (i=0;i<len;i++)
        DFS(v[x][i],niv+1);
}

inline void ParcurgereEuler(int x)
{
    int i,len;
    if (!viz[x]) {aparitii[x]=lg+1;viz[x]=1;}
    len=v[x].size();
    for (i=0;i<len;i++)
        {
            Euler[++lg]=x;
            ParcurgereEuler(v[x][i]);
        }
    Euler[++lg]=x;
}

inline void RMQ()
{
    int i,aux,put;
    mat[lg][0]=Euler[lg];
    for (i=lg-1;i>=1;i--)
        {
            if (nivel[Euler[i]]<nivel[Euler[i+1]]) mat[i][0]=Euler[i];
            else mat[i][0]=Euler[i+1];
            aux=lg-i;
            put=1;
            while (puteri[put]<=aux)
                {
                    if (nivel[mat[i][put-1]]<nivel[mat[i+puteri[put-1]][put-1]]) mat[i][put]=mat[i][put-1];
                    else mat[i][put]=mat[i+puteri[put-1]][put-1];
                    put++;
                }
        }
    logaritm[2]=1;
    for (i=3;i<=200000;i++)
        logaritm[i]=logaritm[i>>1]+1;
}

inline void Rezolva()
{
    int i,x,y,aux;
    while (m--)
        {
            fin>>x>>y;
            if (aparitii[x]>aparitii[y]) swap(x,y);
            aux=aparitii[y]-aparitii[x];
            if (nivel[mat[aparitii[x]][logaritm[aux]]]<nivel[mat[aparitii[y]-puteri[logaritm[aux]]][logaritm[aux]]])
                fout<<mat[aparitii[x]][logaritm[aux]];
            else fout<<mat[aparitii[y]-puteri[logaritm[aux]]][logaritm[aux]];
            fout<<"\n";
        }
}

int main()
{
    int i;
    fin>>n>>m;
    for (i=1;i<=n-1;i++)
        {
            fin>>a[i];
            v[a[i]].push_back(i+1);
        }
    puteri[0]=1;
    for (i=1;i<=22;i++)
        puteri[i]=puteri[i-1]<<1;
    DFS(1,1);
    ParcurgereEuler(1);
    RMQ();
    Rezolva();
    /*for (i=1;i<=lg;i++)
        {
            for (int j=0;j<=19;j++)
                fout<<mat[i][j]<<" ";
            fout<<"\n";
        }
    for (i=1;i<=n;i++)
        fout<<aparitii[i]<<" ";*/
    return 0;
}