Pagini recente » Cod sursa (job #3361483) | Cod sursa (job #3361322) | Cod sursa (job #3361489) | Cod sursa (job #3361944) | Cod sursa (job #3361406)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int MAX_N = 100000,
MAX_POW2 = 262144,
INF = 1000000000;
inline void swap(int& x, int& y)
{
x ^= y ^= x ^= y;
}
//inline int min(int x, int y) { return (x < y) ? x : y; }
//inline void minSelf(int& x, int y) { x = (x < y) ? x : y; }
int NextPow2(int n)
{
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n + 1;
}
struct SegmentTree
{
int tree[MAX_POW2 << 1];
int *arr;
int n;
inline int Combine(int x, int y)
{
return (arr[x] < arr[y]) ? x : y;
}
void Build(int* arr, int n)
{
this->n = NextPow2(n);
this->arr = arr;
this->arr[0] = INF;
for(int i = 1; i < this->n; i++)
tree[this->n + i - 1] = (i <= n) ? i : 0;
for(int i = this->n - 1; i >= 1; i--)
tree[i] = Combine(tree[i << 1], tree[i << 1 | 1]);
}
int Query(int left, int right)
{
int res = 0;
left += this->n - 1;
right += this->n - 1;
while(left <= right)
{
if(left & 1)
res = Combine(res, tree[left++]);
if(!(right & 1))
res = Combine(res, tree[right--]);
left >>= 1;
right >>= 1;
}
return res;
}
};
struct Tree
{
vector<int> adj[MAX_N + 1];
int euler[MAX_N << 1],
depth[MAX_N << 1],
pos[MAX_N + 1];
int n, q, timer = 0;
SegmentTree segTree;
void Read()
{
f >> n >> q;
for(int y = 2; y <= n; y++)
{
int x;
f >> x;
adj[x].push_back(y);
}
}
void DFS(int node, int dist)
{
++timer;
euler[timer] = node;
depth[timer] = dist;
pos[node] = timer;
for(int child : adj[node])
{
DFS(child, dist + 1);
++timer;
euler[timer] = node;
depth[timer] = dist;
}
}
void BuildSegTree()
{
DFS(1, 0);
segTree.Build(depth, timer);
}
int LCA(int x, int y)
{
int left = pos[x],
right = pos[y];
if(left > right)
swap(left, right);
return euler[segTree.Query(left, right)];
}
void Solve()
{
while(q--)
{
int x, y;
f >> x >> y;
g << LCA(x, y) << '\n';
}
}
};
Tree tree;
int main()
{
tree.Read();
tree.BuildSegTree();
tree.Solve();
f.close();
g.close();
return 0;
}