Cod sursa(job #2542902)

Utilizator ViAlexVisan Alexandru ViAlex Data 10 februarie 2020 18:13:43
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include<bits/stdc++.h>
using namespace std;

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


int node_count,query_count;
int parent[100001];
vector<int> children[100001];


int euler[200002],depths[200002],first_aparition[100001],length=0;

int rmq[20][100001];


void read()
{
    int m,a,b;
    in>>node_count>>query_count;

    for(int i=2; i<=node_count; i++)
    {
        in>>parent[i];
        children[parent[i]].push_back(i);
    }
}

void build_rmq()
{
    for(int i=0; i<length; i++)
    {
        rmq[0][i]=i;
    }



    for(int i=1; (1<<i)<length; i++)
    {
        int len=1<<i;
        int up=1<<(i-1);
        for (int k=0; k<=length-len; k++)
        {
            rmq[i][k]=rmq[i-1][k];

            if(depths[rmq[i-1][k]]>depths[rmq[i-1][k+up]])
                rmq[i][k]=rmq[i-1][k+up];
        }

    }
}

int query(int a,int b)
{

    int x=first_aparition[a];
    int y=first_aparition[b];

    if(x>y)
        swap(x,y);

    int segment_length=y-x+1;

    int lg=log2(segment_length);
    int ramas=segment_length-(1<<lg);

    int p=rmq[lg][x];
    int q=rmq[lg][x+ramas];


    if(depths[p]>depths[q])
        return euler[q];
    return euler[p];


}


void dfs(int index,int depth)
{
    euler[length]=index;
    depths[length]=depth;
    first_aparition[index]=length;

    length++;

    for(int i=0; i<children[index].size(); i++)
    {
        dfs(children[index][i],depth+1);
        euler[length]=index;
        depths[length]=depth;
        length++;

    }
}

void solve()
{
    int a,b;
    dfs(1,0);

    build_rmq();
    for(int i=0; i<query_count; i++)
    {
        in>>a>>b;
        out<<query(a,b)<<'\n';
    }
}



int main()
{
    read();
    solve();
}