- 分享
1月7日考试t4做法(需要树剖优化)
- @ 2026-1-8 16:08:45
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+20;
int n,q,fa[N],dep[N],LOG,up[N][20],md[N];
vector<int> G[N],mds[N],out;
void add(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
}
bool md_cmp(int a,int b){
return md[a]>md[b];
}
void dfs(int u,int f){
fa[u]=f;
md[u]=dep[u];
//mds[u].push_back(u);
for(auto v:G[u]){
if(v==f) continue;
dep[v]=dep[u]+1;
dfs(v,u);
md[u]=max(md[u],md[v]);
mds[u].push_back(v);
}
sort(mds[u].begin(),mds[u].end(),md_cmp);
}
int init(){
LOG=log2(n)+1;
for(int i=1;i<=n;i++){
up[i][0]=fa[i];
}
for(int j=1;j<LOG;j++){
for(int i=1;i<=n;i++){
up[i][j]=up[up[i][j-1]][j-1];
}
}
return 0;
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
for(int i=LOG-1;i>=0;i--){
if(dep[up[u][i]]>=dep[v]){
u=up[u][i];
}
}
if(u==v){
return u;
}
for(int i=LOG-1;i>=0;i--){
if(up[u][i]!=up[v][i]){
u=up[u][i];
v=up[v][i];
}
}
return fa[u];
}
int dist(int x,int y){
return dep[x]+dep[y]-2*dep[lca(x,y)];
}
int dd(int u,int v,int k){//从u到v的最大深度子孙节点(不包含k)的距离
//cout<<u<<" "<<v<<" "<<k<<" ";
for(auto now:mds[v]){
if(lca(now,k)==v){
//cout<<md[now]+dep[u]-2*dep[lca(now,u)]<<"\n";
return md[now]+dep[u]-2*dep[lca(now,u)];
}
}
//cout<<dist(u,v)<<"\n";
return dist(u,v);
}
int main(){
//freopen("problem.in","r",stdin);
//freopen("problem.out","w",stdout);
cin>>n;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
add(u,v);
}
dep[1]=1;
dfs(1,0);
init();
cin>>q;
while(q--){
int a,b,ans=0;
cin>>a>>b;
if(dep[a]<dep[b]){
swap(a,b);
}
//b比a高
ans=max(md[a]-dep[a],(dist(a,b))/2);
int l=lca(a,b),d=dist(a,b);
//cout<<d<<" ";
if(dep[l]<dep[b]){
ans=max(ans,md[b]-dep[b]);
}else{
ans=max(ans,dd(b,b,a));
}
int t=fa[a],cnt=0;
while(dist(t,a)<=dist(t,b)){
ans=max(ans,dd(a,t,a));
t=fa[t];
}
while(t!=l){
ans=max(ans,dd(b,t,a));
t=fa[t];
}
t=fa[b];
while(t!=0){
ans=max(ans,dd(b,t,b));
t=fa[t];
}
out.push_back(ans);
//cout<<"===="<<endl;
}
for(auto x:out){
printf("%d\n",x);
}
return 0;
}
0 条评论
目前还没有评论...