Cod sursa(job #2445779)

Utilizator AndreiStanescuAlloys Nokito AndreiStanescu Data 5 august 2019 15:07:46
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
/*#include<bits/stdc++.h>
#define nmax 100000
#define log2nmax 17

using namespace std;

int lookup[nmax][log2nmax];
//lookup[i][j]=indicele valori minime din intervalul i...i+2^j-1

void preprocess(int arr[],int n)
{
    int i,j;
    //initializare
    for(i=0;i<n;i++)
        lookup[i][0]=i;

    for(j=1;(1<<j)<n;j++)
    for(i=0;i+(1<<j)-1<n;i++)
    if(arr[lookup[i][j-1]]<=arr[lookup[i+(1<<(j-1))][j-1]])
    lookup[i][j]=lookup[i][j-1];
    else
        lookup[i][j]=lookup[i+(1<<(j-1))][j-1];

}

int query(int l,int r,int arr[])
{
    int dim=(int)log2(r-l+1);
    if(arr[lookup[l][dim]]<=arr[lookup[r-(1<<dim)+1][dim]])
        return arr[lookup[l][dim]];
    else
        return arr[lookup[r-(1<<dim)+1][dim]];

}


int main()
{
    ifstream fin("rmq.in");
    ofstream fout("rmq.out");
    int n,arr[nmax],i,m,a,b;
    fin>>n>>m;
    for(i=0;i<n;i++)
        fin>>arr[i];
    preprocess(arr,n);
    for(i=1;i<=m;i++)
    {
        fin>>a>>b;
        fout<<query(a-1,b-1,arr)<<'\n';
    }
    fin.close();
    fout.close();
}*/
//LCA folosind rmq
#include<fstream>
#include<cmath>
#include<vector>
#define nmax 100000
using namespace std;

int n,m;
vector<int> G[nmax];
int size,euler[3*nmax],lev[18],Pos[3*nmax];
int lookup[nmax][17];

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

void read()
{
    int i,nod;
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>nod;
        G[nod].push_back(i);
    }
}

void Euler_tour(int nod,int level)
{
    euler[++size]=nod;
    lev[size]=level;
    Pos[nod]=size;
    vector<int>::iterator it;
    for(it=G[nod].begin();it!=G[nod].end();it++)
    {
        Euler_tour(*it,level+1);
        euler[++size]=nod;
        lev[size]=level;

    }

}

void preprocess(int arr[],int k)
{
    int i,j;
    //initializare
    for(i=1;i<=k;i++)
        lookup[i][0]=i;

    for(j=1;(1<<j)<=k;j++)
    for(i=1;i+(1<<j)-1<=k;i++)
    if(arr[lookup[i][j-1]]<=arr[lookup[i+(1<<(j-1))][j-1]])
    lookup[i][j]=lookup[i][j-1];
    else
        lookup[i][j]=lookup[i+(1<<(j-1))][j-1];

}

int lca(int nod1,int nod2)
{
    int l,r,dim;
    l=Pos[nod1];
    r=Pos[nod2];
    dim=(int)log2(r-l+1);
    if(lev[lookup[l][dim]]<=lev[lookup[r-(1<<dim)+1][dim]])
        return euler[lookup[l][dim]];
    else
        return euler[lookup[r-(1<<dim)+1][dim]];

}

void solve()
{
    int a,b;
    for(int i=1;i<=m;i++)
    {
        fin>>a>>b;
        fout<<lca(a,b)<<'\n';

    }
}


int main()
{
    read();
    Euler_tour(1,0);
    preprocess(lev,size);
    solve();

}