Cod sursa(job #2575478)

Utilizator mihailrazMihail Turcan mihailraz Data 6 martie 2020 13:43:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
const int nmax=1e5;
int n, m, nre, lvl;
int viz[nmax+5], st[nmax+5], level[2*nmax+5], euler[2*nmax+5], log2[2*nmax+5];
int rmq[2*nmax+5][25];
vector <int> G[nmax+5];

void dfsEu(int nod, int lvl)
{
    viz[nod]=1;
    euler[++nre]=nod;
    level[nre]=lvl;
    st[nod]=nre;
    for(auto vec:G[nod])
        if(!viz[vec])
        {
            dfsEu(vec, lvl+1);
            euler[++nre]=nod;
            level[nre]=lvl;
        }
}

void build(void)
{
    for(int i=2; i<=nre; i++)
        log2[i]=log2[i/2]+1;

    for(int i=1; i<=nre; i++)
        rmq[i][0]=i;

    for(int j=1; j<=log2[nre]; j++)
        for(int i=1; i<=nre-(1<<j)+1; i++)
        {
            rmq[i][j]=rmq[i][j-1];
            if(level[rmq[i+(1<<(j-1))][j-1]]<level[rmq[i][j]])
                rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
        }
}

int query(int fx, int fy)
{
    if(fx>fy)
        swap(fx, fy);
    int lg=log2[fy-fx+1];
    if(level[rmq[fx][lg]]<level[rmq[fy-(1<<lg)+1][lg]])
        return rmq[fx][lg];
    return rmq[fy-(1<<lg)+1][lg];
}

int main()
{
    fi>>n>>m;
    for(int i=2; i<=n; i++)
    {
        int tata;
        fi>>tata;
        G[tata].push_back(i);
    }

    dfsEu(1, 0);

    build();

    while(m--)
    {
        int x, y;
        fi>>x>>y;
        fo<<euler[query(st[x], st[y])]<<"\n";
    }

    fi.close();
    fo.close();
    return 0;
}