题目传送门: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$,有被卡风险,故写了该题解的做法。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define L long long 5 #define M 65 6 using namespace std; 7 L f[M]={0},fa[M]={0},fb[M]={0},an,bn; 8 int main(){ 9 f[1]=1; f[2]=1; for(int i=3;i<M;i++) f[i]=f[i-1]+f[i-2]; 10 int cas; cin>>cas; while(cas--){ 11 //int x,y; scanf("%d%d",&x,&y); 12 L x,y; scanf("%lld%lld",&x,&y); 13 memset(fa,0,sizeof(fa)); memset(fb,0,sizeof(fb)); an=bn=0; 14 int t=1; while(f[t]<x) t++; 15 while(f[t]){ 16 while(f[t]>=x) t--; 17 fa[++an]=x; x-=f[t]; 18 } 19 t=1; while(f[t]<y) t++; 20 while(f[t]){ 21 while(f[t]>=y) t--; 22 fb[++bn]=y; y-=f[t]; 23 } 24 int i,j; 25 for(i=an,j=bn;fa[i]==fb[j]&&i&&j;i--,j--); 26 printf("%lld ",fa[i+1]); 27 //cout<<fa[i+1]<<endl; 28 } 29 30 }