Codeforces Round #809 (Div. 2) E (重构树+st表

link

#include <bits/stdc++.h>
using namespace  std;
//#define  int long long
typedef long long ll;
typedef pair<int,int> pii;
#define x first
#define y second
#define pb  push_back
#define inf 1e18
#define IOS   std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define  fer(i,a,b)  for(int i=a;i<=b;i++)
#define  der(i,a,b)  for(int i=a;i>=b;i--)
const int maxn=1e5+10;
const int mod=1e9+7;
int qmi(int a,int b) {
	int res=1;
	while(b) {
		if(b&1) res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}
const int N=3e5+100;
int dr[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};
int n,k;
int  m,q;
int son[N];
int top[N];
int st[N][22];
int siz[N];
int d[N];
int fa[N];
int lg[N];
int f[N];
vector<int>g[N];
int  find(int x) {
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void dfs(int u,int fa) {
	d[u]=d[fa]+1;
	f[u]=fa;
	siz[u]=1;
	int ma=-1;
	for(auto v:g[u]) {
		if(v==fa)continue;
		dfs(v,u);
		siz[u]+=siz[v];
		if(ma<siz[v]) {
			son[u]=v,ma=siz[v];
		}
	}
}
void dfs2(int u,int ff){
	top[u]=ff;
	if(!son[u])return;
	dfs2(son[u],ff);
	for(auto v:g[u]){
		if(v!=f[u]&&v!=son[u])dfs2(v,v);
	}
}
int lca(int x,int y){
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]])swap(x,y);
		x=f[top[x]];
	}
	return d[x]<d[y]?x:y;
}

int query(int l,int r){
	if(l>r)return 0;
	int len=lg[r-l+1];
//	cout<<l<<" "<<len<<endl;
//	cout<<st[l][len]<<" "<<st[r-(1<<len)+1][len];
	return  max(st[l][len],st[r-(1<<len)+1][len]);
}

void solve() {
	cin>>n>>m>>q;
	for(int i=1;i<=n+m;i++)d[i]=siz[i]=son[i]=f[i]=top[i]=0,fa[i]=i,g[i].clear();
	for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
	fer(i,1,m) {
		int x,y;
		cin>>x>>y;
		int a=find(x);
		int b=find(y);
		if(a==b)continue;
		fa[a]=fa[b]=n+i;
	//	cout<<n+i;
		g[a].push_back(n+i),g[n+i].push_back(a);
		g[b].push_back(n+i),g[n+i].push_back(b);
	}
    dfs(find(1),0);dfs2(find(1),find(1));
 	for(int i=1;i<n;++i) st[i][0]=lca(i,i+1)-n;
		for(int j=1;j<20;++j){
			for(int i=1;i+(1<<j)-1<n;++i){
				st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
			}
		}
	//	cout<<query(1,1);
    while(q--){
    	int l,r;
    	cin>>l>>r;
    	if(l==r)cout<<0<<" ";
    	else cout<<query(l,r-1)<<" ";
	}
	cout<<endl;

}

int main() {
	IOS;
	int _;
	cin>>_;
	while(_--) solve();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值