Pagini recente » Cod sursa (job #1505737) | Cod sursa (job #620719) | Cod sursa (job #1984033) | Cod sursa (job #2311736) | Cod sursa (job #2362105)
#include <bits/stdc++.h>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector<int> graf[100005];
vector<int> euler;
bool viz[100005];
int level[100005];
struct lca
{
lca(int Node = 0, int Depth = -1)
{
node = Node;
depth = Depth;
}
int node, depth;
};
lca sparseTable[100005][20];
int n, m;
void read()
{
f >> n >> m;
for (int i = 2, tempParent; i <= n; i++)
{
f >> tempParent;
graf[i].push_back(tempParent);
graf[tempParent].push_back(i);
}
}
int dfs(int node, int lv)
{
euler.push_back(node);
level[node] = lv;
viz[node] = true;
for (int i = 0; i < graf[node].size(); i++)
{
if (!viz[graf[node][i]])
{
dfs(graf[node][i], lv + 1);
euler.push_back(node);
}
}
}
void gen_sparse_table()
{
for (int i = 1; i <= euler.size(); i++)
{
sparseTable[0][i] = lca(euler[i - 1], level[euler[i-1]]);
}
for (int i = 1; i <= log2(euler.size()); i++)
{
for (int j = 1; j < euler.size() - ((int)pow(2, i) - 1); j++)
{
if (sparseTable[i - 1][j].depth < sparseTable[i - 1][j + (int)pow(2, i - 1)].depth)
sparseTable[i][j] = sparseTable[i - 1][j];
else
sparseTable[i][j] = sparseTable[i - 1][j + (int)pow(2, i - 1)];
}
}
}
int query(int node1, int node2)
{
bool found1 = false, found2 = false;
int n1i, n2i;
for(int i = 0; i < euler.size() && (!found1 || !found2); i++)
{
if(!found1 && euler[i] == node1)
{
found1 = true;
n1i = i + 1;
}
if(!found2 && euler[i] == node2)
{
found2 = true;
n2i = i + 1;
}
}
if(n1i > n2i) swap(n1i, n2i);
int chunkSize = (int) log2(n2i - n1i + 1);
int a = sparseTable[chunkSize][n1i].depth;
int b = sparseTable[chunkSize][n2i - (int)pow(2, chunkSize) + 1].depth;
if(a > b)
return sparseTable[chunkSize][n2i].node;
else
return sparseTable[chunkSize][n1i].node;
}
int main()
{
read();
dfs(1, 0);
gen_sparse_table();
for(int i = 0, node1, node2; i < m; i++)
{
f>>node1>>node2;
g<<query(node1, node2)<<'\n';
}
}