Cod sursa(job #2749417)

Utilizator CronosClausCarare Claudiu CronosClaus Data 6 mai 2021 17:19:22
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <bits/stdc++.h>

using namespace std;

const int mxn = 100 * 1000 + 10;

int n, m;

int lvl[ mxn ];
int arb[ 4 * mxn ];

vector< int > g[ mxn ];
vector< int > euler;
int indexx[ mxn ];


void dfs(int x, int level){
    euler.push_back( x );
    lvl[ x ] = level;
    indexx[ x ] = euler.size() - 1;
    for(auto it: g[ x ]){
        if(lvl[ it ] == 0){
            dfs( it, level + 1);
            euler.push_back( x );
        }
    }
}

void build(int st, int sf, int nod){
    if(st == sf){
        arb[ nod ] = st;
        return;
    }

    int mid = (st + sf) / 2;

    build(st, mid, 2 * nod + 1);
    build(mid + 1, sf, 2 * nod + 2);

    if(lvl[ euler[ arb[ 2 * nod + 1] ] ] < lvl[ euler[ arb[ 2 * nod + 2] ] ]){
        arb[ nod ] = arb[ 2 * nod + 1 ];
    }
    else{
        arb[ nod ] = arb[ 2 * nod + 2];
    }
}

int query(int st, int sf, int nod, int x, int y){
    if(x > sf || y < st){
        return indexx[ 0 ];
    }

    if(x <= st && y >= sf){
        return arb[ nod ];
    }

    int mid = (st + sf) / 2;

    int v1 = query(st, mid, 2 * nod + 1, x, y);
    int v2 = query(mid + 1, sf, 2 * nod + 2, x, y);

    if(lvl[ euler[ v1 ]] < lvl[ euler[ v2 ]]){
        return v1;
    }
    else{
        return v2;
    }
}

int lca(int x, int y){
    if(indexx[ x ] > indexx[ y ]){
        swap(x, y);
    }
    return euler[ query(0, euler.size() - 2, 0, indexx[ x ], indexx[ y ]) ];
}

int main()
{
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    cin>> n >> m;

    for(int i = 2, x; i <= n; i++){
        cin>> x;
        g[ i ].push_back( x );
        g[ x ].push_back( i );
    }

    dfs(1, 1);

    build(0, euler.size() - 1, 0);
    euler.push_back( 0 );
    indexx[ 0 ] = euler.size() - 1;
    lvl[ 0 ] = INT_MAX;

    for(int i = 0, x, y; i < m; i++){
        cin>> x >> y;
        cout<< lca(x, y) << '\n';
    }

    return 0;
}