1. 程式人生 > 實用技巧 >【5257】小X的佛光

【5257】小X的佛光

5257. 小X的佛光(Standard IO)

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