P6374 「StOI-1」树上询问

/*
结论显然
if(lcaa==z) cout<<n-jump(x,lcaa)-jump(y,lcaa)<<'\n';
else if(in(x,z)&&in(y,z)==0) cout<<siz[z]-jump(x,z)<<'\n';
else if(in(x,z)==0&&in(y,z)) cout<<siz[z]-jump(y,z)<<'\n';
else cout<<"0\n";
    
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
//#include<queue>
//#include<vector>
//#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=5e5+10 ;
const int inf=0x3f3f3f3f;

int n,q;
int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
int fa[maxn][30],tim[maxn],dep[maxn],dfstm,siz[maxn];

void add(int u,int v){
    to[++tot]=v,nxt[tot]=head[u],head[u]=tot;
}

void dfs(int u,int faa)
{
    dep[u]=dep[faa]+1; fa[u][0]=faa; tim[u]=++dfstm; siz[u]=1;
    for(int i=1;i<=25;i++) fa[u][i]=fa[fa[u][i-1]][i-1];
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(v==faa) continue;
        dfs(v,u);
        siz[u]+=siz[v];
    }
}
int lca (int x,int y)
{
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=25;i>=0;i--)//二进制诬陷分割 
        if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
    if(x==y) return x;
    
    for(int i=25;i>=0;i--)
    {
        if(fa[x][i]!=fa[y][i])
        {
            x=fa[x][i];
            y=fa[y][i];
        }       
    }
    return fa[x][0];
}

int in(int x,int z) {return (tim[z]<=tim[x]&&tim[x]<=tim[z]+siz[z]-1);}

int jump(int x,int faa) {//x一直jump(倍增)到fa子节点的位置
    if(x==faa) return 0;
    for(int i=25;i>=0;--i)
        if(dep[fa[x][i]]>dep[faa])
            x=fa[x][i];
    return siz[x];
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>q;
//    cout<<n<<q;
    
    for(int i=1;i<=n-1;i++){
        int a,b;cin>>a>>b;
        add(a,b),add(b,a);
    }
    dfs(1,1);
    for(int i=1;i<=q;i++){
        int x,y,z;cin>>x>>y>>z;
        int lcaa=lca(x,y);
    //    cout<<lcaa<<endl;
        
        if(lcaa==z) cout<<n-jump(x,lcaa)-jump(y,lcaa)<<'\n';
        else if(in(x,z)&&in(y,z)==0) cout<<siz[z]-jump(x,z)<<'\n';
        else if(in(x,z)==0&&in(y,z)) cout<<siz[z]-jump(y,z)<<'\n';
        else cout<<"0\n";
         
    }
    return 0;
}

 

posted @ 2023-09-22 20:37  JMXZ  阅读(19)  评论(0)    收藏  举报