65pts求助
查看原帖
65pts求助
748744
seika27楼主2024/5/6 17:22

用树链剖分求出公共祖先,然后用线段树求1到公共祖先的最大编号

https://www.luogu.com.cn/record/158217594

#include <bits/stdc++.h>
#define int long long 
#define cin std::cin
#define cout std::cout
const int N=1e5+5;
int cnt;
int n,q,m;
int fa[N],dep[N],son[N],top[N],siz[N],id[N],wt[N],c[N];
std::vector<int>g[N];
void dfs1(int x,int f)
{
	fa[x]=f;
	dep[x]=dep[f]+1;
	siz[x]=1;
	for(register int i=0;i<g[x].size();++i)
	{
		int v=g[x][i];
		if(v==f)continue;
		dfs1(v,x);
		siz[x]+=siz[v];
		if(siz[son[x]]<siz[v])son[x]=v;
	}
}
void dfs2(int x,int topf)
{
	top[x]=topf;
	id[x]=++cnt;
	wt[cnt]=c[x];
	if(!son[x])return;
	dfs2(son[x],topf);
	for(register int i=0;i<g[x].size();++i)
	{
		int v=g[x][i];
		if(v==fa[x]||v==son[x])continue;
		dfs2(v,v);
	}
}
int lca(int x,int y)
{
	while(top[x]!=top[y])
	{

		if(dep[top[x]]<dep[top[y]])std::swap(x,y);
		x=fa[top[x]];
	}

	if(dep[x]>dep[y])std::swap(x,y);
	return x;
}
int lar[N<<2];
#define lx (x<<1)
#define rx (x<<1|1)
#define mid (L+R>>1)
#define max std::max
void up(int x)
{
	lar[x]=max(lar[lx],lar[rx]);
}
void build(int x,int L,int R)
{
	if(L==R)
	{
		lar[x]=wt[L];
		return;
	}
	build(lx,L,mid);
	build(rx,mid+1,R);
	up(x);
}
int query(int x,int L,int R,int l,int r)
{
	if(l<=L&&R<=r)return lar[x];
	int ans=-1e9-9;
	if(l<=mid)ans=max(ans,query(lx,L,mid,l,r));
	if(r>mid)ans=max(ans,query(rx,mid+1,R,l,r));
	return ans;
}
signed main()
{
	std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n;
	for(register int i=1;i<n;++i)
	{
		int x;
		cin>>x;
		g[x+1].push_back(i+1);
		c[i+1]=i+1;
	}
	c[1]=1;
	dfs1(1,0);
	dfs2(1,0);
	build(1,1,n);
	cin>>q;
	for(register int i=1;i<=q;++i)
	{
		cin>>m;
		int xlca;
		cin>>xlca;
		xlca++; 
		for(register int j=1;j<m;++j)
		{
			int x;
			cin>>x;
			x++;
			xlca=lca(xlca,x);
		}
		cout<<query(1,1,n,id[1],id[xlca])-1<<'\n';
	}
}
2024/5/6 17:22
加载中...