Codeforces - E. Company

题目链接:Codeforces - E. Company


我们注意到,一个序列的LCA,只可能是序列当中dfs序最大的和最小的的LCA,然后去除的点,也只能是最大的dfs序,和最小的dfs,暴力判断即可。

重点:一个序列的LCA,只可能是序列当中dfs序最大的和最小的的LCA

线段树维护区间max,min。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,q;
int in[N],out[N],cnt,dfn[N];
int h[N],f[N][20],lg[N];
int mx[N<<2],mi[N<<2];
vector<int> g[N];
void dfs(int x,int fa){
	h[x]=h[fa]+1; f[x][0]=fa; in[x]=++cnt; dfn[cnt]=x;
	for(int i=1;(1<<i)<=h[x];i++)	f[x][i]=f[f[x][i-1]][i-1];
	for(auto to:g[x])	dfs(to,x);	out[x]=cnt;
}
void build(int p,int l,int r){
	if(l==r){mx[p]=mi[p]=in[l];	return ;}
	int mid=l+r>>1;
	build(p<<1,l,mid);	build(p<<1|1,mid+1,r);
	mx[p]=max(mx[p<<1],mx[p<<1|1]);
	mi[p]=min(mi[p<<1],mi[p<<1|1]);
}
int askmax(int p,int l,int r,int ql,int qr){
	if(l==ql&&r==qr)	return mx[p];
	int mid=l+r>>1;
	if(qr<=mid)	return askmax(p<<1,l,mid,ql,qr);
	else if(ql>mid)	return askmax(p<<1|1,mid+1,r,ql,qr);
	else return max(askmax(p<<1,l,mid,ql,mid),askmax(p<<1|1,mid+1,r,mid+1,qr));
}
int askmin(int p,int l,int r,int ql,int qr){
	if(l==ql&&r==qr)	return mi[p];
	int mid=l+r>>1;
	if(qr<=mid)	return askmin(p<<1,l,mid,ql,qr);
	else if(ql>mid)	return askmin(p<<1|1,mid+1,r,ql,qr);
	else return min(askmin(p<<1,l,mid,ql,mid),askmin(p<<1|1,mid+1,r,mid+1,qr));
}
inline int lca(int x,int y){
	if(h[x]<h[y])	swap(x,y);
	while(h[x]>h[y])	x=f[x][lg[h[x]-h[y]]-1];
	if(x==y)	return x;
	for(int i=lg[h[x]]-1;i>=0;i--)
		if(f[x][i]!=f[y][i])	x=f[x][i],y=f[y][i];
	return f[x][0];
}
inline int getlca(int l,int r){
	if(l>r)	return -1;
	return lca(dfn[askmin(1,1,n,l,r)],dfn[askmax(1,1,n,l,r)]);	
}
inline int get(int l,int r,int x){
	int a=getlca(l,x-1),b=getlca(x+1,r);
	if(a==-1||b==-1)	return a+b+1;
	return lca(a,b);
}
signed main(){
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	cin>>n>>q;
	for(int i=2,x;i<=n;i++)	cin>>x,g[x].push_back(i);
	for(int i=1;i<=n;i++)	lg[i]=lg[i-1]+(1<<lg[i-1]==i);
	dfs(1,1);	build(1,1,n);
	while(q--){
		int l,r,p;	cin>>l>>r;
		int u=dfn[askmin(1,1,n,l,r)],v=dfn[askmax(1,1,n,l,r)];
		int c=lca(u,v),a=get(l,r,u),b=get(l,r,v);
		int mx=max(h[c],max(h[a],h[b]));
		if(mx==h[c])	p=l;
		else if(mx==h[a])	p=u;
		else	p=v;
		cout<<p<<' '<<mx-1<<'\n';
	}
	return 0;
}
发布了483 篇原创文章 · 获赞 241 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104101860