Pagini recente » Borderou de evaluare (job #1114944) | Borderou de evaluare (job #2718928) | Borderou de evaluare (job #1365019) | Borderou de evaluare (job #1294291) | Cod sursa (job #3168513)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, q;
vector<int> v[100005];
pair<int, int> euler[200005];
int nr;
int viz[100005];
int t[200005][25];
int first[100005];
void dfs(int nod, int nivel)
{
viz[nod] = 1;
nr++;
euler[nr] = {nod, nivel};
for(auto j: v[nod])
{
if(viz[j] == 0)
{
dfs(j, nivel + 1);
nr++;
euler[nr] = {nod, nivel};
}
}
}
int main()
{
in>>n>>q;
int w;
for(int i = 2; i<=n; i++)
{
in>>w;
v[w].push_back(i);
}
dfs(1, 0);
/*for(int i = 1; i<=nr; i++)
{
out<<euler[i].first<<" ";
}
out<<'\n';
for(int i = 1; i<=nr; i++)
{
out<<euler[i].second<<" ";
}
out<<'\n';*/
for(int i = 1; i<=nr; i++)
{
if(first[euler[i].first] == 0)
{
first[euler[i].first] = i;
}
}
/*for(int i = 1; i<=n; i++)
{
out<<first[i]<<" ";
}
out<<'\n';*/
int put = 1;
int m = log2(nr) + 1;
for(int j = 1; j<=m; j++)
{
if(j == 1)
{
for(int i = 1; i<=nr-put+1; i++)
{
t[i][j] = i;
}
}
else
{
for(int i = 1; i<=nr-put+1; i++)
{
if(euler[t[i][j-1]].second < euler[t[i+(put/2)][j-1]].second)
{
t[i][j] = t[i][j-1];
}
else
{
t[i][j] = t[i+(put/2)][j-1];
}
}
}
put *= 2;
}
int nod1, nod2;
int x, y, k, l, p;
int m1, m2;
while(q--)
{
in>>nod1>>nod2;
x = first[nod1];
y = first[nod2];
if(x > y)
{
swap(x, y);
}
//out<<x<<" "<<y<<" -> ";
l = y - x + 1;
k = (int)log2(l);
m1 = t[x][k+1];
p = l - pow(2, k);
m2 = t[x+p][k+1];
//out<<euler[m1].second <<" "<< euler[m2].second<<" -> ";
if(euler[m1].second <= euler[m2].second)
{
out<<euler[m1].first<<'\n';
}
else
{
out<<euler[m2].first<<'\n';
}
}
return 0;
}