Cod sursa(job #2738339)

Utilizator marinaoprOprea Marina marinaopr Data 5 aprilie 2021 18:34:07
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <stdio.h>
#include <vector>
#include <utility>

#define NMAX 100005
#define INF 1e9

using namespace std;

FILE *fin = fopen("lca.in", "r");
FILE *fout = fopen("lca.out", "w");

vector <int> graf[NMAX];
vector <pair <int, int> > parc;

int n,m,k,x,y,first[NMAX],arbint[4*NMAX],i;
bool viz[NMAX];

void dfs(int nod, int niv)
{
    int i;

    parc.push_back(make_pair(nod, niv));
    if(!viz[nod])
    {
        first[nod] = parc.size()-1;
        viz[nod] = true;
    }

    if(!graf[nod].empty())
        for(i=0; i<=graf[nod].size()-1; ++i)
            if(!viz[graf[nod][i]])
            {
                dfs(graf[nod][i], niv+1);
                parc.push_back(make_pair(nod, niv));
            }
}

void build(int nod, int st, int dr)
{
    int mij;

    if(st == dr)
    {
        arbint[nod] = st;
        return;
    }

    mij = (st+dr) /2;
    build(2*nod, st, mij);
    build(2*nod+1, mij+1, dr);

    if(parc[arbint[2*nod]].second < parc[arbint[2*nod+1]].second)
        arbint[nod] = arbint[2*nod];
    else
        arbint[nod] = arbint[2*nod+1];
}

int query(int nod, int st, int dr, int a, int b)
{
    int ans,mij,q;

    if(a<=st and b>=dr)
        return arbint[nod];

    ans = k;
    mij = (st+dr)/2;
    if(a <= mij)
    {
        q = query(2*nod, st, mij, a, b);
        if(parc[q].second < parc[ans].second)
            ans = q;
    }
    if(b > mij)
    {
        q = query(2*nod+1, mij+1, dr, a, b);
        if(parc[q].second < parc[ans].second)
            ans = q;
    }
    return ans;
}

int main()
{
    fscanf(fin, "%d%d", &n,&m);
    for(i=2; i<=n; ++i)
    {
        fscanf(fin, "%d", &x);
        graf[x].push_back(i);
    }

    dfs(1, 1);

    k = parc.size();

    build(1, 0, k-1);

    parc.push_back(make_pair(0, INF));

    while(m--)
    {
        fscanf(fin, "%d%d", &x,&y);
        if(first[y] < first[x])
            swap(x, y);

        fprintf(fout, "%d\n", parc[query(1, 0, k-1, first[x], first[y])].first);
    }

    fclose(fin);
    fclose(fout);
    return 0;
}