lca 转 rmq 只过了一个点 求助
查看原帖
lca 转 rmq 只过了一个点 求助
572133
潘德理2010楼主2023/11/23 22:34
#include<bits/stdc++.h>
using namespace std;
struct st_table{// st 表 
	int f[1000010][20],s;
	int que(int x,int y){ // 查询 x 到 y 的区间内的最小值 
		if(x==y) return f[x][0];
		if(x>y) swap(x,y);
		int d=log2(y-x);
		return min(f[x][d],f[x+(1<<d)][d]);
	}
	void init(queue<int> q){// st 表初始化 
		while(!q.empty()){
			f[++s][0]=q.front();
			q.pop();
		}
		for(int i=2,k=1;i<s;i*=2,k++){
			for(int j=1;j+i-1<=s;j++){
				f[j][k]=que(j,j+i-1);
			}
		}
	}
}st;
queue<int> r;
vector<int> e[500010];//邻接表 
int n,q,a,b;
int p[500010],d[500010],c[500010],t;
//p[]欧拉序 ,d[]为 dfs 序 ,c[i] 表示 dfs 序为 i 的数 
void dfs1(int u,int fa){//搜索确定欧拉序 
	d[u]=++t;
	r.push(d[u]);
	p[u]=r.size();
	c[d[u]]=u;
	for(int i=0;i<int(e[u].size());i++){
		int v=e[u][i];
		if(v==fa) continue;
		dfs1(v,u);
		r.push(d[u]);
	}
}
int lca(int x,int y){
	return c[st.que(p[x],p[y])];
}
int main(){
	int rt;
	scanf("%d%d%d",&n,&q,&rt);
	for(int i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}	
	dfs1(rt,0);
	st.init(r);
	while(q--){
		scanf("%d%d",&a,&b);
		printf("%d\n",lca(a,b));
	}
} 

2023/11/23 22:34
加载中...