Pagini recente » Cod sursa (job #1506852) | Cod sursa (job #2828217) | Cod sursa (job #2673650) | Cod sursa (job #1142241) | Cod sursa (job #1502280)
#include <fstream>
#include <bitset>
#include <vector>
#include <utility>
#include <algorithm>
#define NMAX 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, k = 1;
int first[NMAX];
vector <int> p2max;
vector <vector <int> > G;
vector <vector <int> > rmq;
void euler(int nod)
{
first[nod] = k;
rmq[0].push_back(nod); ++k;
for (vector<int> ::iterator it = G[nod].begin(); it != G[nod].end(); ++it)
if (!first[*it])
{
euler(*it);
rmq[0].push_back(nod); ++k;
}
}
void make_p2max()
{
p2max.push_back(0); p2max.push_back(0);
for (int i = 2; i < 5 * NMAX; ++i)
p2max.push_back(p2max[i / 2] + 1);
}
void make_rmq()
{
for (int i = 1; (1 << i) < k; ++i)
{
rmq.push_back(*new vector<int>);
for (int j = 0; j + (1 << i) - 1 < k; ++j)
rmq[i].push_back(min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
}
}
int query(int x, int y)
{
if (x > y) swap(x, y);
int imax = p2max[y - x];
return min(rmq[imax][x], rmq[imax][y - (1 << imax) + 1]);
}
int main()
{
int x, y;
fin >> n >> m;
G.assign(n + 10, *new vector<int>);
for (int i = 2; i <= n; ++i)
{
fin >> x;
G[x].push_back(i);
G[i].push_back(x);
}
rmq.push_back(*new vector<int>);
rmq[0].push_back(0);
euler(1);
make_rmq();
make_p2max();
for (int i = 0; i < m; ++i)
{
fin >> x >> y;
fout << query(first[x], first[y]) << '\n';
}
return 0;
}