Cod sursa(job #2466799)

Utilizator roberttrutaTruta Robert roberttruta Data 2 octombrie 2019 22:51:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <fstream>
#include <vector>
using namespace std;
vector <int> a[100005];
int x,y,n,m,q,k,p,Min1,Min2;
int pw[100],ln[200005],v[200005],poz[400005][32],e[200005],lv[100005],viz[100005];
void dfs(int start, int level)
{int i;
    viz[start]=++n;
    e[n]=start;
    lv[start]=level;
    for(i=0;i<a[start].size();i++)
    if(!viz[a[start][i]])
    {
        dfs(a[start][i],level+1);
        e[++n]=start;
    }
}
void RMQ()
{int i,j;
    pw[0]=1;
    for(i=1;i<=30;i++)
    pw[i]=pw[i-1]*2;
    k=0;
    for(i=1;i<=n;i++)
    if(i==pw[k])
    {
        ln[i]=k;
        k++;
    }
    else
        ln[i]=k-1;

    for(i=1;i<=n;i++)
    poz[i][0]=i;

    for(j=1;j<=ln[n];j++)
    for(i=1;i<=n;i++)
    if(v[ poz[i][j-1] ] < v[ poz[i+pw[j-1]][j-1] ])
    poz[i][j]=poz[i][j-1];
    else
    poz[i][j]=poz[i+pw[j-1]][j-1];
}
int main()
{
    ifstream f("lca.in");
    ofstream g("lca.out");
///lca(x,y)=nodul cu cel mai mic nivel situat intre
///prima aparitie a lui x si prima aparitie a lui y
///in parcurgerea df a arborelui

int i;
    f>>m>>q;
    for(i=2;i<=m;i++)
    {
        f>>x;
        a[x].push_back(i);
    }
    dfs(1,1);
    for(i=1;i<=n;i++)
    v[i]=lv[e[i]];
    RMQ();

    for(i=1;i<=q;i++)
    {
        f>>x>>y;
        x=viz[x];
        y=viz[y];
        if(x>y)
        swap(x,y);
        k=y-x;
        k=ln[k];
        Min1=v[poz[x][k]];
        p=y-x-pw[k]+1;
        Min2=v[poz[x+p][k]];
        if(Min1<Min2)
        g<<e[poz[x][k]]<<'\n';
        else
        g<<e[poz[x+p][k]]<<'\n';
    }

    return 0;
}