【5257】小X的佛光

Description

 

Input

Output

 

Sample Input

3 3 1
1 2
2 3
1 2 3
1 1 3
3 1 3

Sample Output

1
1
3

很明显,就是LCA问题,就计算的时候可以用分类讨论,也可以用一条公式概括全部情况,

即 (range(A,B)+range(B,C)-range(A,C))/2+1 = answer

注意到这里还不行,你得给你的简单函数加个inline,防止爆栈。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
#define R register
using namespace std;
typedef long long ll;
ll n,p,num,t;
const ll MAXN=200020;
ll f[MAXN][25],d[MAXN];
ll ver[2*MAXN],head[2*MAXN],Next[2*MAXN];
ll tot=0;
inline void add(ll x,ll y){
    ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
} 
queue<ll> q;
inline void bfs(){
    q.push(1);
    d[1]=1;
    while(q.size()){
        long x=q.front();
        q.pop();
        ll y;
        for(R ll i=head[x];i;i=Next[i]){
        y=ver[i];
        if(d[y]) continue;
        d[y]=d[x]+1;
        f[y][0]=x;
        for(R ll j=1;j<=t;j++)
        f[y][j]=f[f[y][j-1]][j-1];
        q.push(y);    
        }
    }
}
ll lca(ll x,ll y){
    if(d[x]>d[y]) swap(x,y);
    for(R ll i=t;i>=0;i--)
    if(d[f[y][i]]>=d[x]) y=f[y][i];
    if(x==y) return x;
    for(R ll i=t;i>=0;i--)
    if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
ll range(ll x,ll y){
    return d[x]+d[y]-2*d[lca(x,y)];
} 
int main(){
    scanf("%lld%lld%lld",&n,&p,&num);
    ll x,y;
    for(R ll i=1;i<=n-1;i++)
    {
    scanf("%lld%lld",&x,&y);
    add(x,y);add(y,x);    
    }
    t=(ll)(log(n)/log(2))+1;
    bfs();
    ll a,b,c;
    ll ans=0;
    for(R ll i=1;i<=p;i++){
        scanf("%lld%lld%lld",&a,&b,&c);
        ans=0;
        ans=(range(a,b)+range(c,b)-range(a,c))/2+1;
        printf("%lld\n",ans);
    }
}

若转载,请注明出处:https://cnblogs.com/yuzhe123

猜你喜欢

转载自www.cnblogs.com/yuzhe123/p/13366271.html