Pagini recente » Planificare infoarena | Cod sursa (job #1892225) | Cod sursa (job #1878797) | Planificare infoarena | Cod sursa (job #479600)
Cod sursa(job #479600)
#include <fstream>
#include <vector>
using namespace std;
int n, m;
vector<vector<int> > a;
vector<pair<int, int> > b;
vector<int> p;
void df(int v, int niv = 0)
{
p[v] = b.size();
b.push_back(make_pair(v, niv));
for(vector<int>::iterator it = a[v].begin(); it != a[v].end(); ++ it)
{
df(*it, niv + 1);
b.push_back(make_pair(v, niv));
}
}
vector<vector<int> > rmq;
#define nod first
#define nivel second
void buildRMQ()
{
int n = b.size();
int x, y;
rmq.push_back(vector<int>(n));
for(int i=0;i<n;++i)
rmq[0][i] = i;
for(int i=1;(1<<i)<=n;++i)
{
rmq.push_back(vector<int>(n));
for(int j=0;j<n;++j)
{
x = j, y = j + (1 << (i - 1));
if(y >= n) y = n-1;
x = rmq[i-1][x], y = rmq[i-1][y];
if(b[x].nivel <= b[y].nivel)
rmq[i][j] = x;
else
rmq[i][j] = y;
}
}
}
int queryRMQ(int st, int dr)
{
if (st > dr)
swap(st, dr);
int lg = dr - st + 1, j;
for(j=-1;lg;++j, lg >>= 1);
dr = dr - (1 << j) + 1;
st = rmq[j][st]; dr = rmq[j][dr];
if(b[st].nivel <= b[dr].nivel)
return b[st].nod;
return b[dr].nod;
}
inline int query(int x, int y)
{
return queryRMQ(p[x], p[y]);
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
int x, y;
fin >> n >> m;
a.resize(n + 1);
p.resize(n + 1);
for(int i=2;i<=n;++i)
{
fin >> x;
a[x].push_back(i);
}
df(1);
buildRMQ();
while(m--)
{
fin >> x >> y;
fout << query(x, y) << "\n";
}
return 0;
}