Cod sursa(job #2096312)

Utilizator mihaicivMihai Vlad mihaiciv Data 28 decembrie 2017 22:34:23
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100001
#define inf 700001
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,nr,nivel[nmax],val,pos,minim,A,B,Val[5*nmax],val2,pozitie;
struct LCA {
    int niv,val;
}v[4*nmax],arb[10*nmax];
vector <int> a [nmax];
void citire()
{
    f>>n>>m;
    int x ;
    for (int i=2;i<=n;i++) {
        f >> x;
        a[x].push_back(i);
    }
}
void DFS(int x)
{
    for (int i=0;i<a[x].size();i++) {
        int p=a[x][i];
        nivel[p] = nivel[x] + 1;
        v[++nr].val = p;
        v[nr].niv = nivel[p];
        DFS(p);
        v[++nr].val = x;
        v[nr].niv = nivel[x];
    }
}
void Inserare(int nod,int st,int dr)
{
    if (st==dr) {
        arb[nod].niv = val;
        arb[nod].val= val2;
    }
    else {
        int mij = (st + dr) / 2;
        if ( pos <= mij ) {
            Inserare(2*nod,st,mij);
        }
        else {
            Inserare(2*nod+1,mij+1,dr);
        }
        if (arb[2*nod].niv<= arb[2*nod+1].niv) {
            arb[nod].niv=arb[2*nod].niv;
            arb[nod].val=arb[2*nod].val;
        }
        else {
            arb[nod].niv=arb[2*nod+1].niv;
            arb[nod].val=arb[2*nod+1].val;
        }
    }
}
void CreareArbore()
{
    for (int i = 1 ; i <= nr ; i++) {
        pos=i;
        val=v[i].niv;
        val2=v[i].val;
        Inserare(1,1,nr);
    }
}
void Cautare(int nod,int st,int dr)
{
    if (A<=st && dr<=B) {
        if (minim>=arb[nod].niv) {
            minim=arb[nod].niv;
            pozitie=arb[nod].val;
        }
    }
    else {
        int mij = (st+dr)/2;
        if (mij >= A) {
            Cautare(2*nod,st,mij);
        }
        if (mij+1 <= B) {
            Cautare(2*nod+1,mij+1,dr);
        }
    }
}
void Prelucrare1()
{
    for (int i=1;i<=nr;i++) {
        if (Val[v[i].val]==0) {
            Val[v[i].val]=i;
        }
    }
}
void rez()
{
    nivel[1] = 1;
    v[++nr].val = 1;
    v[nr].niv = 1;
    DFS(1);
    /*
    for (int i=1;i<=nr;i++) {
        cout << v[i].val << " ";
    }
    cout << "\n";
    for (int i = 1 ; i <= nr ; i++) {
        cout << v[i].niv << " ";
    }
    */
    Prelucrare1();
    CreareArbore();
    int u,v;
    for (int i = 1; i <= m ; i++) {
        f >> u >> v;
        A = Val[u];
        B = Val[v];
        if (A>B) {
            swap(A,B);
        }
        minim = inf;
        pozitie=0;
        Cautare(1,1,nr);
        g << pozitie << "\n";
    }
}
int main()
{
    citire();
    rez();
    return 0;
}