Cod sursa(job #1192771)

Utilizator andreeadeacAndreea Ioana Deac andreeadeac Data 29 mai 2014 19:11:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <fstream>
#include<vector>
using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

/*void euler(int x)
{
    prelucreaza x
    for y fiu al lui x
    {
        euler(y);
        prelucreaza x
    }
}

r[i][[j] = varful cu nivelul cel mai mic din intervalul [j-2^i + 1, j]
r[i][j] = min(r[i-1][j], r[i-1][j-(1<<(i-1)))])

precalculam si vectorul lg[i] = parte intreaga din log in baza 2 din i
val = 1;
for(i=1 ; i<=n ; i++){
    if(i > (1<<val))
        val++;
    lg[i] = val;
}
q(a,b) = min(r[lg[ab]][a+ab-1], r[lg[ab]][b]), unde ab = b-a+1

notam k1 = r[i-1][j-(1<<(i-1))]
si k2 = r[i-1][j]
r[i][j] =   k1 daca nivel[k1]<nivel[k2]
            k2 altfel
*/
const int N=100000;
int nivel[N+1], poz[N+1], c[2*N+1], asc[N+1], lg[2*N+1], r[18][2*N+1], n, m, nr, viz[N+1];
vector <int> t[N+1];
void euler(int nod){
    int x;
   viz[nod]++;
   nr++;
   c[nr]=nod;
   for(int i=0;i< t[nod].size();i++)
       if(viz[t[nod][i]]==0){
            x=t[nod][i];
            nivel[x]=nivel[nod]+1;
            poz[x]=nr+1;
            euler(x);
            nr++;
            c[nr]=nod;
        }
}
int minim(int a, int b){
    if(nivel[a]<nivel[b])
        return a;
    else
        return b;
}

void rmq(){
    int i,j,val;
    for(i=1;i<=nr;i++)
        r[0][i]=c[i];
    for(i=2 ; i<=nr ; i++)
        lg[i] = lg[i >> 1] + 1;
    for(i=1;(1<<i)<=nr;i++)
        for(j=1;j<=nr;j++)
            r[i][j]=minim(r[i-1][j], r[i-1][j+(1<<(i-1))]);

}
int main()
{
    int i,x,y,p,j;
    in>>n>>m;
    for(i=2;i<=n;i++){
        in>>asc[i];
        t[asc[i]].push_back(i);
    }
    euler(1);
    //return 0;
    rmq();
    /*for(i=1;(1<<i)<=nr;i++){
        for(j=1;j<=nr;j++)
            out<<r[i][j]<<" ";
        out<<"\n";
    }*/
    //return 0;
    for(i=1;i<=m;i++){
        in>>x>>y;
        x=poz[x];
        y=poz[y];
        if(x==0 || y==0)
            out<<"1\n";
        else{
            if(x>y)
            {
                int aux = x;
                x = y;
                y = aux;
            }
            p=lg[y-x+1];
            out<<minim(r[p][x], r[p][y-(1<<p)+1])<<"\n";
        }
    }
    return 0;
}