站外题求助卡常
  • 板块学术版
  • 楼主charm1
  • 当前回复8
  • 已保存回复8
  • 发布时间2021/10/17 18:27
  • 上次更新2023/11/4 03:28:25
查看原帖
站外题求助卡常
135258
charm1楼主2021/10/17 18:27
#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
const int logn=20;
int n,m,d1,d2,sum,cnt;
int head[maxn],q[maxn],fa[maxn][logn],dep[maxn],siz[maxn],son[maxn][logn],son1[maxn],son2[maxn],mem[maxn],tag[maxn];
bool del;
struct edge{
    int v,nxt;
}a[maxn<<1];
inline void add(int x,int y){
    ++cnt;
    a[cnt].v=y;
    a[cnt].nxt=head[x];
    head[x]=cnt;
}
inline int read(){
    int ret=0,f=1;  char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){ret=ret*10+ch-'0';ch=getchar();}
    return ret*f;
}
inline int LCA(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    for(int k=19;k>=0;k--){
        int f=fa[x][k];
        if(dep[f]>=dep[y]) x=f;
    }
    if(x==y) return x;
    for(int k=19;k>=0;k--){
        int fx=fa[x][k],fy=fa[y][k];
        if(fx!=fy) x=fx,y=fy;
    }
    return fa[x][0];
}
inline int check(int x){
    if(del){
        int f=LCA(d1,x);
        if(f==x) return siz[d1];
        if(f==d1)return siz[x];
        return 0;
    }
    int f1=LCA(d1,x),f2=LCA(d2,x);
//  cout<<x<<" fa "<<f1<<" "<<f2<<endl;
    if(f1==d1||f2==d2) return siz[x];
    return (f1==x)*siz[d1]+(f2==x)*siz[d2];
}
inline int Getsz(int x){return tag[x]==m?mem[x]:tag[x]=m,mem[x]=(x?siz[x]-check(x):0);}
inline int Getmx(int x){
    int s1=son1[x],s2=son2[x],s3=son[x][0];
    int sz1=Getsz(s1),sz2=Getsz(s2),sz3=Getsz(s3);
    if(sz1>=sz2&&sz1>=sz3) return s1;
    if(sz2>=sz1&&sz2>=sz3) return s2;
    if(sz3>=sz1&&sz3>=sz2) return s3;    
}
void dfs1(int x,int f){
    siz[x]=1;
    int s1=0,s2=0,s3=0;
    for(int k=head[x];k;k=a[k].nxt){
        int v=a[k].v;
        if(v==f) continue;
        dfs1(v,x); siz[x]+=siz[v];
        if(siz[v]>siz[s1]){
            s3=s2; s2=s1; s1=v;
            continue;
        }
        if(siz[v]>siz[s2]){
            s3=s2; s2=v;
            continue;
        }
        if(siz[v]>siz[s3]) s3=v;
    }
    son[x][0]=s1; son1[x]=s2; son2[x]=s3;
}
void scan(){
    n=read(); m=read();
    for(int k=1;k<n;k++){
        int x,y;
        x=read(); y=read();
        add(x,y); add(y,x);
    }
}
void GetLCA(){
    int l,r;
    q[l=r=1]=1;
    while(l<=r){
        int x=q[l++],f=fa[x][0];
        dep[x]=dep[f]+1;
        for(int k=head[x];k;k=a[k].nxt){
            int v=a[k].v;
            if(v==f) continue;
            q[++r]=v; fa[v][0]=x;
        }
        for(int k=1;k<logn;k++)
        fa[x][k]=fa[fa[x][k-1]][k-1];
    }
}
void Getson(){
    dfs1(1,0);
    for(int i=1;i<logn;i++)
    for(int k=1;k<=n;k++)
    son[k][i]=son[son[k][i-1]][i-1];
}
void prework(){
    GetLCA();
    Getson();
}
void solve(){
    while(m--){
        d1=read(); d2=read();
        if(d1==1||d2==1){
            puts("0");
            continue;
        }
        if(dep[d1]>dep[d2]) swap(d1,d2);
        del=(LCA(d1,d2)==d1);
        if(del) sum=siz[d1];
        else sum=siz[d1]+siz[d2];
        sum=n-sum;
        int x=1;
        while(1){
            int s=son[x][0],gs=Getmx(x),sgs=Getsz(gs);
            if(sgs<=(sum>>1)){
                if(sgs==(sum+1>>1)){
                    if(gs>x) swap(gs,x);
                    printf("%d %d\n",gs,x);
                    break;
                }
                int sf=fa[x][0];
                if((Getsz(x)<<1)==sum){
                    if(sf>x) swap(sf,x);
                    printf("%d %d\n",sf,x);
                }
                else printf("%d\n",x);
                break;
            }
            if(s!=gs){
                x=gs;
                continue;
            }
            for(int k=19;k>=0;k--){
                int ss=son[x][k];
                if(Getsz(ss)>=(sum+1>>1)) x=ss;
            }
        }
    }
}
signed main(){
    freopen("random.in","r",stdin);
    freopen("random1.out","w",stdout);
    scan(); prework(); solve();
    return 0;
}
/*
5 100
1 2
1 3
2 4
2 5
3 4
*/
2021/10/17 18:27
加载中...