Pagini recente » Cod sursa (job #454183) | Cod sursa (job #2832044) | Cod sursa (job #1745052) | Istoria paginii runda/pu/clasament | Cod sursa (job #2028649)
#include <bits/stdc++.h>
#define Nmax 100006
using namespace std;
int n,P[Nmax],S[Nmax],fst[Nmax],t,u,v,q,nr,NRA[Nmax],x,y;
bool R[Nmax];
struct edge{
int nod;
bool p,s;
};
vector<edge> V[Nmax];
vector<pair<int,int> > E;
pair<int,int> rmq[21][Nmax*2];
void dfs(int nod,int nr)
{
NRA[nod] = nr;
for (auto it : V[nod])
{
P[it.nod] = P[nod] + it.p;
S[it.nod] = S[nod] + it.s;
dfs(it.nod,nr);
}
}
void euler(int nod,int niv)
{
fst[nod] = E.size();
E.push_back({nod,niv});
for (auto it : V[nod])
{
euler(it.nod,niv+1);
E.push_back({nod,niv});
}
}
int LCA(int a,int b)
{
int x = log2(abs(fst[b]-fst[a]));
if (rmq[x][min(fst[a],fst[b])].second<=rmq[x][max(fst[a],fst[b]) - (1<<x) + 1].second)
return rmq[x][min(fst[a],fst[b])].first;
return rmq[x][max(fst[a],fst[b]) - (1<<x) + 1].first;
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
cin>>n>>q;
for (int i=2;i<=n;i++)
{
cin>>x;
if (x==-1)
{
R[i] = true;
continue;
}
V[x].push_back({i,(y==1),(y==0)});
}
R[1] = true;
for (int i=1;i<=n;i++)
if (R[i]==true)
{
dfs(i,++nr);
euler(i,1);
}
int mx = log2(E.size());
for (int i=0;i<=mx;i++)
for (int j=0;j<E.size()-(1<<i)+1;j++)
{
if (i==0)
{
rmq[i][j] = E[j];
continue;
}
if (rmq[i-1][j].second>rmq[i-1][j+(1<<(i-1))].second)
rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
else
rmq[i][j] = rmq[i-1][j];
}
for (int i=1;i<=q;i++)
{
cin>>x>>y;
cout<<LCA(x,y)<<'\n';
}
/*cin>>q;
for (int i=1;i<=q;i++)
{
cin>>t>>u>>v;
if (t==1)
{
if (NRA[v]==NRA[u] && LCA(v,u)==u && S[u]-S[v]==E[fst[u]].second - E[fst[v]].second && v!=u)
cout<<"YES\n";
else
cout<<"NO\n";
}
else
{
int x;
if (NRA[v] == NRA[u])
x = LCA(v,u);
if (NRA[v] == NRA[u] && P[x]-P[v]==E[fst[x]].second - E[fst[v]].second && S[x]-S[u]==E[fst[x]].second - E[fst[u]].second && v!=u)
cout<<"YES\n";
else
cout<<"NO\n";
}
}*/
return 0;
}