Cod sursa(job #2041931)

Utilizator mihaicivMihai Vlad mihaiciv Data 17 octombrie 2017 21:25:53
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100001
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector <int> a[nmax];
int pozitia;
int n,m,p[5*nmax],vis[nmax],d[nmax],nr,nivel[nmax],poz,val,a1,b1;
struct arbore11
{
    int valo,pozi;
}arb[5*nmax];
void Cautare(int nod,int st,int dr)
{
    if (a1<=st && dr<=b1)
    {
        if (val>arb[nod].valo)
        {
            val=arb[nod].valo;
            pozitia=p[arb[nod].pozi];
        }
        //val=min(val,p[arb[nod].pozi]);
    }
    else
    {
        int mij=(st+dr)/2;
        if (a1<=mij)
        {
            Cautare(2*nod,st,mij);
        }
        if (b1>=mij+1)
        {
            Cautare(2*nod+1,mij+1,dr);
        }
    }
}
int LCA(int x,int y)
{
    val=100001;
    if (d[x]<d[y])
    {
        a1=d[x];
        b1=d[y];
    }
    else
    {
        a1=d[y];
        b1=d[x];
    }
    Cautare(1,1,nr);
    return pozitia;
}
void rezolvare()
{
    int x,y;
    f>>x>>y;
    g<<LCA(x,y)<<"\n";
}
void DFS(int x)
{
    p[++nr]=x;
    for (int i=0;i<a[x].size();i++)
    {
        int l=a[x][i];
        //cout<<l<<" ";
        if (vis[l]==0)
        {
            nivel[l]=nivel[x]+1;
            DFS(l);
            p[++nr]=x;
        }
    }
}
void Euler()
{
    nivel[1]=0;
    vis[1]=1;
    DFS(1);
}
void Distanta()
{
    for (int i=1;i<=nr;i++)
    {
        if (d[p[i]]==0)
        {
            d[p[i]]=i;
        }
    }
}
void Arbore(int nod,int st,int dr)
{
    if (st==dr)
    {
        arb[nod].valo=val;
        arb[nod].pozi=st;
    }
    else
    {
        int mij=(st+dr)/2;
        if (poz<=mij)
        {
            Arbore(2*nod,st,mij);
        }
        else
        {
            Arbore(2*nod+1,mij+1,dr);
        }
        if (arb[2*nod].valo>arb[2*nod+1].valo)
        {
            arb[nod].valo=arb[2*nod+1].valo;
            arb[nod].pozi=arb[2*nod+1].pozi;
        }
        else
        {
            arb[nod].valo=arb[2*nod].valo;
            arb[nod].pozi=arb[2*nod].pozi;
        }
        //arb[nod]=min(arb[2*nod],arb[2*nod+1]);
    }
}
void ArboreInterval()
{
    for (int i=1;i<=nr;i++)
    {
        poz=i;
        val=nivel[p[i]];
        Arbore(1,1,nr);
    }
    /*
    for (int i=1;i<=nr;i++)
    {
        cout<<p[arb[i].pozi]<<" ";
    }
    */
}
void citire()
{
    f>>n>>m;
    int x,y;
    for (int i=2;i<=n;i++)
    {
        f>>x;
        a[x].push_back(i);
    }
    Euler();
    Distanta();
    ArboreInterval();
    for (int i=1;i<=m;i++)
    {
        rezolvare();
    }
}
int main()
{
    citire();
    return 0;
}