Cod sursa(job #2412376)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 22 aprilie 2019 10:34:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <cstdio>
#include <vector>
#define DIMN 100010
using namespace std;
int eul[5*DIMN],nv[5*DIMN],first[DIMN];
int d[20][5*DIMN];
int log[5*DIMN];
vector <int> v[DIMN];
int elem;
void dfs (int nod,int niv){
    int i,vecin;
    eul[++elem]=nod;
    nv[elem] = niv;
    first[nod] = elem; /// prima poz;
    for (i=0;i<v[nod].size();i++){
        vecin=v[nod][i];
        dfs(vecin,niv+1);
        eul[++elem]=nod;
        nv[elem]=niv;
    }
}
int query (int x,int y){
    int px,py,len;
    px=first[x];
    py=first[y];
    /// minimul din intervalul px py
    /// in d e pozitia din eul unde e nivelul minim
    if (px>py)
        swap(px,py);
    len = py-px+1;
    if (nv[ d[log[len]][px] ] < nv[ d[log[len]][py-(1<<log[len])+1] ])
        return d[log[len]][px];
    return d[log[len]][py-(1<<log[len])+1];
}
int main()
{
    FILE *fin=fopen ("lca.in","r");
    FILE *fout=fopen ("lca.out","w");
    int n,q,i,x,pow,y;
    fscanf (fin,"%d%d",&n,&q);
    for (i=1;i<n;i++){
        fscanf (fin,"%d",&x);
        v[x].push_back(i+1);
    }
    for (i=2;i<=2*n;i++)
        log[i] = log[i/2] + 1;

    dfs (1,1);

    /// rmq pe eul
    for (i=1;i<=elem;i++){
        d[0][i] = i;
    }

    for (pow=1;pow<=log[elem];pow++){
        for (i=1;i + (1<<pow)-1 <=elem;i++){
            if (nv[d[pow-1][i]] < nv[d[pow-1][i + (1<<(pow-1))]])
                d[pow][i] = d[pow-1][i];
            else d[pow][i] = d[pow-1][i + (1<<(pow-1))];
        }
    }

    for (;q;q--){
        fscanf (fin,"%d%d",&x,&y);
        fprintf (fout,"%d\n",eul[query(x,y)]);
    }
    return 0;
}