【題解】洛谷 P3938 斐波那契【20201013 CSP 模擬賽】
阿新 • • 發佈:2020-10-14
題意
第一個月有 \(1\) 對兔子,編號為 \(1\),之後每個月,年齡大於 \(1\) 的兔子會生一對新的兔子(如同斐波那契數列的模型),新生兔子按出生時間編號,出生時間相同則按雙親編號小的編號小。\(m\) 次詢問 \(x\) 和 \(y\) 的最近公共祖先。\(m\leq 3\times 10^5\),\(x,y\leq 10^{12}\)。
題解
\(x\) 的父親為 \(x\) 減去小於 \(x\) 的最大的斐波那契數。樹深是 \(\log\) 級別的,於是暴力往上跳即可。
程式碼:
#include<bits/stdc++.h> using namespace std; #define ll long long ll getint(){ ll ans=0,f=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9'){ ans=ans*10+c-'0'; c=getchar(); } return ans*f; } ll f[62],cnt=2; int main(){ // freopen("t1.in","r",stdin); // freopen("t1.out","w",stdout); int m=getint(); f[0]=f[1]=1; for(cnt=2;f[cnt-1]<=1e12;cnt++){ f[cnt]=f[cnt-1]+f[cnt-2]; } while(m --> 0){ ll x=getint(),y=getint(); int p=cnt-1; while(x!=y){ (x<y)?swap(x,y),0:0; while(f[p]>=x)--p; x-=f[p]; } printf("%lld\n",x); } return 0; }