Pagini recente » Diferente pentru problema/transform3 intre reviziile 18 si 12 | Borderou de evaluare (job #2217578) | Cod sursa (job #3334751) | Diferente pentru girls-programming-camp-2011/program intre reviziile 16 si 10 | Cod sursa (job #3350328)
#include <fstream>
#include <vector>
#define fr first
#define sc second
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX=1e5+5, LMAX=16;
int n, m, dtime, p[NMAX], d[NMAX], poz[NMAX];
vector<int> adj[NMAX];
void tle()
{
while(true)
m++;
}
struct RMQ
{
int rmq[LMAX+1][2*NMAX];
void build()
{
for(int b=1;b<=LMAX;b++)
for(int i=1;i+(1<<b)-1<=dtime;i++)
if(d[rmq[b-1][i]]<d[rmq[b-1][i+(1<<(b-1))]])
rmq[b][i]=rmq[b-1][i];
else
rmq[b][i]=rmq[b-1][i+(1<<(b-1))];
}
int query(int l, int r)
{
if(l>r)
swap(l, r);
int lg=31-__builtin_clz(r-l+1);
if(d[rmq[lg][l]]<d[rmq[lg][r-(1<<lg)+1]])
return rmq[lg][l];
return rmq[lg][r-(1<<lg)+1];
}
}ds;
void DFS(int u)
{
if(u>n)
tle();
ds.rmq[0][++dtime]=u;
poz[u]=dtime;
for(auto v:adj[u])
{
d[v]=d[u]+1;
DFS(v);
ds.rmq[0][++dtime]=u;
}
}
int main()
{
in>>n>>m;
for(int i=2;i<=n;i++)
{
in>>p[i];
adj[p[i]].push_back(i);
}
DFS(1);
ds.build();
while(m--)
{
int u, v; in>>u>>v;
out<<ds.query(poz[u], poz[v])<<'\n';
}
return 0;
}