Codeforces - E. Company

Topic links: codeforces - Company E.


We note that a sequence of LCA, which can only be dfs sequence order of the largest and smallest of the LCA, and then remove the point, can only be the largest order dfs, dfs and minimal, violence can be judged.

Key: a sequence of LCA, which can only be dfs sequence order of the largest and smallest of LCA

Segment tree maintenance interval max, min.


AC Code:

#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;
}
Published 483 original articles · won praise 241 · views 30000 +

Guess you like

Origin blog.csdn.net/weixin_43826249/article/details/104101860