Pagini recente » Cod sursa (job #2227029) | Cod sursa (job #320161) | Istoria paginii runda/16_februarie_simulare_oji_2024_clasa_9/clasament | Cod sursa (job #2394330) | Cod sursa (job #1669758)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <bitset>
#include <algorithm>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX = 100001;
int n,m;
vector<int> muchii[NMAX];
stack<int> st;
bitset<NMAX> mark;
vector<int> euler;
int high[NMAX];
vector<int> height;
int pos[NMAX];
int **sp;
int *lg;
void citire()
{
in>>n>>m;
int x;
for(int i=1;i<n;i++)
{
in>>x;
muchii[x].push_back(i+1);
}
}
void dfs()
{
mark.set(1);
st.push(1);
int y = 0;
int target,ok;
while(!st.empty())
{
y = st.top();
euler.push_back(y);
if(y!=1)
{
if(!pos[y])
pos[y] = euler.size()-1;
}
ok = 0;
for(unsigned int i=0;i<muchii[y].size();i++)
if(!mark.test(muchii[y][i]))
{
target = muchii[y][i];
ok = 1;
break;
}
if(ok)
{
high[target] = high[y]+1;
st.push(target);
mark.set(target);
}
else
st.pop();
}
}
void sparse_table()
{
lg = new int[height.size()+1];
lg[1] = 0;
lg[0] = 0;
for(unsigned int i=2;i<=height.size();i++)
lg[i] = lg[i/2] + 1;
sp = new int*[height.size()+1];
for(unsigned int i=0;i<=height.size();i++)
sp[i] = new int[18];
for(unsigned int i=0;i<height.size();i++)
sp[i][0] = i;
for(unsigned int j=1;(unsigned int)(1<<j)<=height.size();j++)
for(unsigned int i=0;i+(1<<j)-1<height.size();i++)
if(height[sp[i][j-1]] <= height[sp[i+(1<<(j-1))][j-1]])
sp[i][j] = sp[i][j-1];
else
sp[i][j] = sp[i+(1<<(j-1))][j-1];
}
int main()
{
citire();
dfs();
for(unsigned int i=0;i<euler.size();i++)
height.push_back(high[euler[i]]);
sparse_table();
int x,y;
int k;
int ind;
for(int i=1;i<=m;i++)
{
in>>x>>y;
if(pos[x] > pos[y])
swap(x,y);
k = lg[pos[y]-pos[x]+1];
if(height[sp[pos[x]][k]] <= height[sp[pos[y]-(1<<k)+1][k]])
ind = sp[pos[x]][k];
else
ind = sp[pos[y]-(1<<k)+1][k];
out<<euler[ind]<<"\n";
}
in.close();
out.close();
return 0;
}