Pagini recente » Cod sursa (job #3360567) | Cod sursa (job #3361629) | Cod sursa (job #3361463)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int MAX_N = 100000,
MAX_LOG2 = 18,
INF = 1000000000;
struct SparseTable
{
int st[MAX_LOG2 + 1][MAX_N << 1];
int log2[MAX_N << 1];
int *arr;
int n;
int Combine(int x, int y)
{
return (arr[x] < arr[y]) ? x : y;
}
void Init(int *arr, int n)
{
this->arr = arr;
this->arr[0] = INF;
this->n = n;
}
void Preprocess()
{
log2[1] = 0;
for(int i = 2; i <= n; i++)
log2[i] = log2[i >> 1] + 1;
for(int i = 1; i <= n; i++)
st[0][i] = i;
for(int p = 1; p <= log2[n]; p++)
for(int i = 1; i + (1 << p) - 1 <= n; i++)
st[p][i] = Combine(st[p - 1][i], st[p - 1][i + (1 << (p - 1))]);
}
int Query(int left, int right)
{
int len = log2[right - left + 1];
return Combine(st[len][left], st[len][right - (1 << len) + 1]);
}
};
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;
SparseTable sparseTable;
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 = 0)
{
++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 InitSparseTable()
{
timer = 0;
DFS(1);
sparseTable.Init(depth, timer);
sparseTable.Preprocess();
}
int LCA(int x, int y)
{
int left = pos[x],
right = pos[y];
if(left > right)
swap(left, right);
return euler[sparseTable.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.InitSparseTable();
tree.Solve();
f.close();
g.close();
return 0;
}