Cod sursa(job #2289510)

Utilizator CronosClausCarare Claudiu CronosClaus Data 24 noiembrie 2018 18:22:50
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <bits/stdc++.h>

using namespace std;

const int mxn = 100 * 1000 + 10;

vector< int > g[ mxn ];

int v[ 2 * mxn ];
int p = 1;

int a[ 8 * mxn ];

int poz[ mxn ];

int n, q;

int st, sf;

void build(int x, int y, int nod){
    if(x == y){
        a[ nod ] = v[ x ];
    }
    else{
        int mid = (x + y) / 2;
        build(x, mid, 2 * nod);
        build(mid + 1, y, 2 * nod + 1);
        a[ nod ] = min(a[ 2 * nod ], a[ 2 * nod + 1]);
    }
}

int query(int x, int y, int nod){
    if(st <= x && y <= sf){
        return a[ nod ];
    }
    else{
        int mij = (x + y)/2;
        int mx1 = mxn, mx2 = mxn;
        if(st <= mij)
            mx1 = query(x, mij, 2 * nod);
        if(mij < sf)
            mx2 = query(mij + 1, y, 2 * nod + 1);
        return min(mx1, mx2);
    }
}

void euler(int nod){
    v[ p++ ] = nod;
    poz[ nod ] = p - 1;
    if(g[ nod ].size()){
        for(auto it: g[ nod ]){
            euler( it );
            v[ p++ ] = nod;
        }
    }
}

int main()
{
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    cin>> n >> q;
    for(int i = 2, x; i <= n; i++){
        cin>> x;
        g[ x ].push_back( i );
    }
    euler( 1 );
    p--;
    build(1, p, 1);
    for(int i = 1, x, y; i <= q; i++){
        cin>> x >> y;
        st = poz[ x ];
        sf = poz[ y ];
        if(st > sf)
            swap(st, sf);
        cout<< query(1, p, 1) << '\n';
    }
    return 0;
}