Pagini recente » Cod sursa (job #1777227) | Cod sursa (job #1297149) | Cod sursa (job #2105877) | Cod sursa (job #1881296) | Cod sursa (job #2874010)
#include <iostream>
#include <fstream>
#include <vector>
const int maxn = 1e5;
const int maxLog = 20 ;
typedef std::pair<int, int> PII ;
std::fstream in ("lca.in", std::ios::in) ;
std::fstream out ("lca.out", std::ios::out) ;
std::vector<int> G[1 + maxn] ;
int path[1 + 5 * maxn], nodesPath ;
int level[1 + 5 * maxn] ;
int firstApp[1 + 5 * maxn] ;
void euler_walk(int node) {
path[++ nodesPath] = node ;
firstApp[node] = nodesPath ;
for (int son : G[node]) {
level[son] = level[node] + 1 ;
euler_walk(son) ;
path[++ nodesPath] = node ;
}
}
namespace RMQ {
PII rmq[1 + maxLog][1 + 5 * maxn] ;
int LOG[1 + 5 * maxn] ;
int putere[1 + maxLog] ;
void precalc(int size) {
for (int i = 2 ; i <= size ; ++ i) {
LOG[i] = LOG[i / 2] + 1 ;
}
putere[0] = 1 ; putere[1] = 2 ;
for (int i = 2 ; putere[i - 1] < size ; ++ i) {
putere[i] = putere[i - 1] * 2 ;
}
}
void makeRmq(int size) {
precalc(size) ;
for (int i = 1 ; i <= size ; ++ i) {
rmq[0][i] = {level[path[i]], path[i]} ;
}
for (int len = 1 ; (1 << len) <= size ; ++ len) {
for (int poz = 1 ; poz + putere[len] - 1 <= size ; ++ poz) {
if (rmq[len - 1][poz].first < rmq[len - 1][poz + putere[len - 1]].first) {
rmq[len][poz] = rmq[len - 1][poz] ;
} else {
rmq[len][poz] = rmq[len - 1][poz + putere[len - 1]] ;
}
}
}
}
int query(int left, int right) {
if (left > right) {
std::swap(left, right) ;
}
int dist(right - left + 1) ;
int len = putere[LOG[dist]] ;
if (rmq[LOG[dist]][left].first < rmq[LOG[dist]][right - len + 1].first) {
return rmq[LOG[dist]][left].second ;
} else {
return rmq[LOG[dist]][right - len + 1].second ;
}
}
}
int main() {
int n, m, x, y ;
in >> n >> m ;
for (int i = 1 ; i <= n - 1 ; ++ i) {
in >> x ;
G[x].push_back(i + 1) ;
}
level[1] = 1 ; euler_walk(1) ;
#if DEBUGP == 1
debugVS(path, nodesPath) ;
for (int i = 1 ; i <= nodesPath ; ++ i) {
std::cerr << level[path[i]] << ' ' ;
}
std::cerr << '\n' ;
#endif
RMQ::makeRmq(nodesPath) ;
for (int i = 1 ; i <= m ; ++ i) {
in >> x >> y ;
out << RMQ::query(firstApp[x], firstApp[y]) << '\n' ;
}
}