Cod sursa(job #2863510)

Utilizator Casian_doispeChiriac Casian Casian_doispe Data 6 martie 2022 20:11:42
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.62 kb
#include <fstream>
#include <vector>
#include <deque>
#include <algorithm>
#include <string>

#define MOD 1999999973
#define INT_MAX 1000000000

using namespace std ;

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

int tatal[100009], e[1000009], lvl[1000009], primaparitie[1000009] ;

vector<int> fii[100009] ;

int peuler(int nod, int poz, int level)
{
    lvl[poz] = level ;
    e[poz ++] = nod ;

    if(fii[nod].size())
    {
        for(int f = 0 ; f < fii[nod].size() ; f ++)
            poz = peuler(fii[nod][f], poz, level + 1), e[poz] = nod, lvl[poz] = level, poz ++ ;

        return poz ;
    }
    else return poz ;
}

struct nod
{
    int mid, val, st, dr ;

    nod *stfiu, *drfiu ;
};

int comp(int a, int b)
{
    if(lvl[a] <= lvl[b])return a ;
    return b ;
}

int query(nod *tatal, int st, int dr)
{
    ///cout << st << " " << dr << "     " << tatal -> st << " " << tatal -> dr << " " << tatal -> mid << "       " << tatal ->val << endl ;

    if(tatal -> st == st && tatal -> dr == dr)
        return tatal -> val ;

    if(dr <= tatal -> mid)
        return query(tatal -> stfiu, st, dr) ;

    if(st >= tatal -> mid + 1)
        return query(tatal -> drfiu, st, dr) ;

    return comp(query(tatal -> stfiu, st, tatal -> mid), query(tatal -> drfiu, tatal -> mid + 1, dr)) ;
}

nod* root = new nod ;

void create(nod *tatal, int st, int dr)
{
    int mid = (st + dr) / 2 ;

    tatal -> st = st ;
    tatal -> dr = dr ;
    tatal -> mid = mid ;

    if(st == dr)
    {
        tatal -> val = mid ;

        return ;
    }

    tatal -> stfiu = new nod ;
    tatal -> drfiu = new nod ;

    create(tatal -> stfiu, st, mid) ;
    create(tatal -> drfiu, mid + 1, dr) ;

    tatal -> val = comp(tatal -> stfiu -> val, tatal -> drfiu -> val) ;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n, q ;

    cin >> n >> q ;

    for(int f = 2 ; f <= n ; f ++)
        cin >> tatal[f], fii[tatal[f]].push_back(f) ;

    int neuler = peuler(1, 1, 0) - 1 ;

    for(int f = 1 ; f <= neuler ; f ++)
        if(!primaparitie[e[f]])primaparitie[e[f]] = f ;

    /// trebe dat indicele elementului minim

    create(root, 1, neuler) ;

    ///cout << rez ;

    ///return 0 ;

    while(q --)
    {
        int st, dr, a, b, mn = INT_MAX ;

        cin >> a >> b ;

        st = primaparitie[a] ;
        dr = primaparitie[b] ;

        if(st > dr)swap(st, dr) ;

        ///cout << st << " " << dr << endl ;

        cout << e[query(root, st, dr)] << '\n' ;
    }

    return 0 ;
}