Pagini recente » Cod sursa (job #1237886) | Cod sursa (job #2087454) | Cod sursa (job #1663578) | Cod sursa (job #385045) | Cod sursa (job #1192771)
#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;
}