Pagini recente » Cod sursa (job #2053920) | Cod sursa (job #857267) | Cod sursa (job #3327929) | Cod sursa (job #2846677) | Cod sursa (job #3309751)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int NMAX=4e5+8;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m;
vector<int> g[NMAX];
int a[NMAX];
int depth[NMAX],st[NMAX],euler[NMAX],timer;
int anc[NMAX];
ll sp[NMAX];
int rmq[19][NMAX];
int lg[NMAX];
void read()
{
fin >> n;
for(int i=1; i<n; i++)
{
int x,y;
fin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
fin >> m;
for(int i=1; i<=m; i++)
fin >> a[i];
}
void dfs(int nod,int daddy,int h)
{
depth[nod]=h;
++timer;
st[nod]=timer;
euler[timer]=nod;
for(auto it:g[nod])
{
if(it==daddy)
continue;
dfs(it,nod,h+1);
euler[++timer]=nod;
}
}
void pre()
{
lg[0]=-1;
for(int i=1; i<=timer; i++)
{
lg[i]=1+lg[i/2];
rmq[0][i]=euler[i];
}
for(int i=1; (1<<i)<=timer; i++)
{
for(int j=1; j<=timer-(1<<i)+1; j++)
{
int l(1<<(i-1));
if(depth[rmq[i-1][j]]<depth[rmq[i-1][j+l]])
rmq[i][j]=rmq[i-1][j];
else
rmq[i][j]=rmq[i-1][j+l];
}
}
}
int lca(int x,int y)
{
int len=abs(st[x]-st[y])+1;
int l=lg[len];
int sh=len-(1<<l);
if(depth[rmq[l][min(st[x],st[y])]]<depth[rmq[l][min(st[x],st[y])+sh]])
return rmq[l][min(st[x],st[y])];
return rmq[l][min(st[x],st[y])+sh];
}
ll solve(int st,int dr)
{
if(st==dr)
return (ll)a[st];
int mij=st+(dr-st)/2;
ll ans=solve(st,mij)+solve(mij+1,dr);
anc[mij]=a[mij];
for(int i=mij-1; i>=st; i--)
anc[i]=lca(anc[i+1],a[i]);
anc[mij+1]=a[mij+1];
for(int i=mij+2; i<=dr; i++)
anc[i]=lca(anc[i-1],a[i]);
sp[dr]=anc[dr];
for(int i=dr-1; i>mij; i--)
sp[i]=sp[i+1]+anc[i];
for(int i=st; i<=mij; i++)
{
int l=mij+1,r=dr;
int u=0;
while(l<=r)
{
int mid=l+(r-l)/2;
if(anc[mid]==lca(anc[mid],anc[i]))
{
u=mid;
r=mid-1;
}
else
l=mid+1;
}
ans+=sp[u];
if(u)
ans+=(1LL*anc[i]*(u-mij-1));
}
return ans;
}
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(nullptr);
fout.tie(nullptr);
//ead();
fin >> n >> m;
for(int i=1; i<n; i++)
{
int x;
fin >> x;
g[x].push_back(i+1);
g[i+1].push_back(x);
}
dfs(1,0,0);
pre();
while(m--)
{
int x,y;
fin >> x >> y;
fout << lca(x,y) << "\n";
}
//cout << solve(1,m);
return 0;
}