Cod sursa(job #2592545)

Utilizator Chirac_MateiChiriac Matei Chirac_Matei Data 1 aprilie 2020 20:46:33
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
struct nodS
{
    int f, par, depth;
    vector <int> cop;
};
int n,m,i,x,y;
nodS nod[100005];
vector <int> euler;
vector <int> aib;
void dfs(int poz)
{
    euler.push_back(poz);
    nod[poz].f = euler.size()-1;
    nod[poz].depth = nod[nod[poz].par].depth+1;

    for(auto it : nod[poz].cop)
    {
        dfs(it);
        euler.push_back(poz);
    }
}
void upd(int i, int val, int st, int dr, int poz)
{
    if(!aib[poz] || nod[aib[poz]].depth>nod[val].depth)
        aib[poz]=val;

    if(st==dr)
        return;

    int mij = (st+dr)/2;

    if(i<=mij)
        upd(i, val, st, mij, 2*poz);
    else
        upd(i, val, mij+1, dr, 2*poz+1);
}
int query(int stt, int drt, int st, int dr, int poz)
{
    if(stt==st && drt==dr)
        return aib[poz];

    int mij = (st+dr)/2;

    if(drt<=mij)
        return query(stt, drt, st, mij, 2*poz);

    if(stt>mij)
        return query(stt, drt, mij+1, dr, 2*poz+1);

    int ans1=query(stt, mij, st, mij, 2*poz);
    int ans2=query(mij+1, drt, mij+1, dr, 2*poz+1);

    if(nod[ans1].depth<nod[ans2].depth)
        return ans1;
    else
        return ans2;
}
void makeaib()
{
    aib.resize(8*n);
    for(i=1;i<=2*n-1;i++)
        upd(i, euler[i], 1, 2*n-1, 1);
}

int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>x;
        nod[i].par=x;
        nod[x].cop.push_back(i);
    }

    euler.push_back(0);
    dfs(1);
    makeaib();

    for(i=1;i<=m;i++)
    {
        fin>>x>>y;

        if(nod[x].f>nod[y].f)
            swap(x, y);

        fout<<query(nod[x].f, nod[y].f, 1, 2*n-1, 1)<<'\n';
    }
    return 0;
}