Pagini recente » Cod sursa (job #2122858) | Cod sursa (job #2364304) | Cod sursa (job #2446861) | Cod sursa (job #2266294) | Cod sursa (job #935274)
Cod sursa(job #935274)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int MAX_N = 100005;
const int MAX_logN = 20;
int n, m, Log[MAX_N << 1], euler[MAX_N << 1], nivel[MAX_N << 1], poz[MAX_N], cnt;
int rmq[MAX_N << 2][MAX_logN];
bool used[MAX_N];
vector <int> L[MAX_N];
void read() {
f >> n >> m;
for (int i = 2; i <= n; i++) {
int x;
f >> x;
L[x].push_back(i);
}
}
void dfs(int nod, int level) {
euler[++cnt] = nod;
nivel[cnt] = level;
poz[nod] = cnt;
for (int i = 0; i < L[nod].size(); i++) {
int vecin = L[nod][i];
if (!used[vecin]) {
dfs(vecin, level + 1);
euler[++cnt] = nod;
nivel[cnt] = level;
}
}
}
void precompute_rmq() {
Log[1] = 0;
for (int i = 2; i <= cnt; i++)
Log[i] = Log[i / 2] + 1;
for (int i = 1; i <= cnt; i++)
rmq[i][0] = i;
for (int j = 1; (1 << j) < cnt; j++)
for (int i = 1; i + (1 << (j - 1)) <= cnt; i++)
if (nivel[rmq[i][j - 1]] <= nivel[rmq[i + (1 << (j - 1))][j - 1]])
rmq[i][j] = rmq[i][j - 1];
else
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
void solve() {
while (m--) {
int i, j, ind;
f >> i >> j;
i = poz[i]; j = poz[j];
if (i > j)
swap(i, j);
int k = Log[j - i + 1];
if (nivel[rmq[i][k]] <= nivel[rmq[j - (1 << k) + 1][k]])
ind = rmq[i][k];
else
ind = rmq[j - (1 << k) + 1][k];
g << euler[ind] << '\n';
}
}
int main() {
read();
dfs(1, 1); // aflu parcurgerea euler si nivelurile
precompute_rmq();
solve();
f.close();
g.close();
return 0;
}