Pagini recente » Cod sursa (job #1671443) | Cod sursa (job #2857249) | Cod sursa (job #1443818) | Cod sursa (job #1156919) | Cod sursa (job #902585)
Cod sursa(job #902585)
#include <fstream>
#include <vector>
#define lmax 18
#define nmax 100100
#define pb push_back
#define mkp make_pair
#define Level(i) Euler[i].second
using namespace std;
vector < pair<int,int> > Euler;
vector <int> Arb[nmax];
int N,M,First[nmax],Log[2*nmax],Rmq[lmax][2*nmax];
int LCA(int x,int y) {
x=First[x];
y=First[y];
if(x>y)
swap(x,y);
if(Level( Rmq[Log[y-x+1]][x] ) < Level( Rmq[Log[y-x+1]][y-(1<<Log[y-x+1])+1] ))
return Euler[Rmq[Log[y-x+1]][x]].first;
else
return Euler[Rmq[Log[y-x+1]][y-(1<<Log[y-x+1])+1]].first;
}
void Dfs(int Nod,int level) {
First[Nod]=Euler.size();
Euler.pb(mkp(Nod,level));
for(int i=0;i<Arb[Nod].size();i++) {
Dfs(Arb[Nod][i],level+1);
Euler.pb(mkp(Nod,level));
}
}
void init() {
int i,j;
Euler.pb(mkp(0,0));
Dfs(1,0);
N<<=1;
for(i=2;i<=N;i++)
Log[i]=Log[i>>1]+1;
for(i=1;i<=N;i++)
Rmq[0][i]=i;
for(i=1;(1<<i)<=N;i++)
for(j=1;j+(1<<i)-1<=N;j++)
if(Level( Rmq[i-1][j] )<Level( Rmq[i-1][j+(1<<(i-1))] ))
Rmq[i][j]=Rmq[i-1][j];
else
Rmq[i][j]=Rmq[i-1][j+(1<<(i-1))];
}
void read(ifstream & in) {
int i,x;
in>>N>>M;
for(i=2;i<=N;i++) {
in>>x;
Arb[x].pb(i);
}
}
int main() {
int x,y;
ifstream in("lca.in");
ofstream out("lca.out");
read(in);
init();
while(M--) {
in>>x>>y;
out<<LCA(x,y)<<'\n';
}
in.close();
out.close();
return 0;
}