Pagini recente » Cod sursa (job #436268) | Cod sursa (job #187507) | Cod sursa (job #308306) | Cod sursa (job #1882219) | Cod sursa (job #974572)
Cod sursa(job #974572)
#include <fstream>
#include <vector>
#include <list>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
#define last (int)(E.size()-1)
#define N 2*n+1
#define min(a,b) ((a < b) ? a : b)
vector <list <int> > g;
vector <vector <int> > rmq;
vector <int> E, f, L, bp;
int n, m;
void swap (int &a, int &b) {
int aux = a;
a = b;
b = aux;
}
void dfs(int x, int val) {
E.push_back(x);
L.push_back(val);
f[x] = last;
for (list <int> :: iterator it = g[x].begin(); it != g[x].end(); ++it) {
dfs(*it, val + 1);
E.push_back(x);
L.push_back(val);
}
}
void RMQ() {
rmq.resize(bp[last]+1);
for (vector <vector <int> > :: iterator it = rmq.begin(); it != rmq.end(); ++it)
(*it).resize(last+1);
for (int i = 1; i <= last; ++i)
rmq[0][i] = i;
for (int i = 1; i <= bp[last]; ++i)
for (int j = 1; j <= last - (1 << i) + 1; ++j) {
rmq[i][j] = rmq[i-1][j];
if (L[rmq[i][j]] > L[rmq[i-1][j + (1 << (i - 1))]])
rmq[i][j] = rmq[i-1][j + (1 << (i - 1))];
}
}
int LCA(int x, int y) {
int a = f[x], b = f[y];
if (a > b)
swap (a, b);
int pow = bp[b - a + 1];
int res = rmq[pow][a];
if (L[res] > L[rmq[pow][b + 1 - (1 << pow)]])
res = rmq[pow][b + 1 - (1 << pow)];
return E[res];
}
int main() {
fin >> n >> m;
E.reserve(N+1);
L.reserve(N+1);
bp.resize(N+1);
f.resize(n+1);
E.push_back(0);
L.push_back(0);
g.resize(n+1);
for (int i = 2; i <= n; ++i) {
int x;
fin >> x;
g[x].push_back(i);
}
dfs(1, 0);
for (int i = 2; i <= last; ++i)
bp[i] = bp[i >> 1] + 1;
RMQ();
while (m--) {
int x, y;
fin >> x >> y;
fout << LCA(x, y) << "\n";
}
}