Pagini recente » Cod sursa (job #2180517) | Cod sursa (job #2169037) | Cod sursa (job #1140771) | Cod sursa (job #1190022) | Cod sursa (job #1411158)
#include <fstream>
#include <vector>
#include <algorithm>
#define INF 666013
#define MAXN 350000
#define MAXLOGN 20
using namespace std;
long n, m, cur_lvl;
vector<long> *tree;
long euler[MAXLOGN][MAXN], ctr, v[MAXLOGN][MAXN], *first_euler;
void buildRMQ()
{
long k, powk, i;
for(k=1, powk=2; powk<=ctr; ++k, powk*=2)
for(i=ctr-powk+1; i>=1; --i)
if(v[k-1][i]<v[k-1][i+powk/2])
{
v[k][i]=v[k-1][i];
euler[k][i]=euler[k-1][i];
}
else
{
v[k][i]=v[k-1][i+powk/2];
euler[k][i]=euler[k-1][i+powk/2];
}
}
long queryRMQ(long x, long y)
{
long k=1, powk=2;
while(powk<=y-x)
{
powk*=2;
++k;
}
--k; powk/=2;
if(v[k][x]<v[k][y-powk+1])
return euler[k][x];
else return euler[k][y-powk+1];
}
long queryLCA(long x, long y)
{
x=first_euler[x];
y=first_euler[y];
if(x>y) swap(x, y);
return queryRMQ(x, y);
}
void pushEuler(long x)
{
++ctr;
euler[0][ctr]=x;
v[0][ctr]=cur_lvl;
if(first_euler[x]>ctr)
first_euler[x]=ctr;
}
void buildEuler(long x)
{
pushEuler(x);
for(vector<long>::iterator it=tree[x].begin(), ed=tree[x].end(); it!=ed; ++it)
{
++cur_lvl;
buildEuler(*it);
--cur_lvl;
pushEuler(x);
}
}
int main()
{
long i, dad, x, y;
ifstream in("lca.in");
ofstream out("lca.out");
in>>n>>m;
tree = new vector<long>[n+1];
first_euler = new long[n+1];
for(i=1; i<=n; ++i) first_euler[i]=INF;
for(i=2; i<=n; ++i)
{
in>>dad;
tree[dad].push_back(i);
}
cur_lvl=0;
buildEuler(1);
buildRMQ();
for(i=0; i<m; ++i)
{
in>>x>>y;
out<<queryLCA(x, y)<<'\n';
}
return 0;
}