题目传送门:https://www.luogu.org/problemnew/show/P3938
这题出得特别吼啊~~
通过打表或者大胆猜想斐波那契数列的一些性质,我们不难发现对于一只兔子$x$,其父亲必为$x-Fk$($F$为斐波那契数列,且$F_{k}$为不大于$x$的最大数字),举个例子:$7-5=2$,$11-8=3$,对于点$x$和点$y$,我们分别求出其所有直系祖宗,然后扫一遍即可。
由于斐波那契数列为指数级增长,故向上跳的复杂度为一个$log$级别,时间复杂度为$O(m*log(max(x_{i},y_{i})))$。
PS:最初我的想法是对于$x$的每一个祖宗都与$y$的祖宗进行比对,结果发现时间复杂度为增多一个$log$,有被卡风险,故写了该题解的做法。
#include<iostream>
#include<cstdio>
#include<cstring>
#define L long long
#define M 65
using namespace std;
L f[M]={},fa[M]={},fb[M]={},an,bn;
int main(){
f[]=; f[]=; for(int i=;i<M;i++) f[i]=f[i-]+f[i-];
int cas; cin>>cas; while(cas--){
//int x,y; scanf("%d%d",&x,&y);
L x,y; scanf("%lld%lld",&x,&y);
memset(fa,,sizeof(fa)); memset(fb,,sizeof(fb)); an=bn=;
int t=; while(f[t]<x) t++;
while(f[t]){
while(f[t]>=x) t--;
fa[++an]=x; x-=f[t];
}
t=; while(f[t]<y) t++;
while(f[t]){
while(f[t]>=y) t--;
fb[++bn]=y; y-=f[t];
}
int i,j;
for(i=an,j=bn;fa[i]==fb[j]&&i&&j;i--,j--);
printf("%lld\n",fa[i+]);
//cout<<fa[i+1]<<endl;
} }