Description
众所周知,斐波那契数列F满足:
F[0]=0,F[1]=1,F[m]=F[m-1]+F [m-2] (m>=2)
现在给出一个数字串S,请找到一个k使得F[k]以S为结尾。
Input
包含一行一个数字串S,S的长度不超过18。
Output
输出满足条件的数字k,且k需要满足0<=k<10^100。若有多组解,输出任意一组,若无解,输出NIE。
Sample Input
025
Sample Output
1525
HINT
请不要提交,尚无SPJ
Source
By Claris
这题真厉害..
看了Claris题解和代码后感到被水淹没,不知所措..
不要怂就是抄
Claris题解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 20
#define LL unsigned long long
using namespace std;
int n;
LL Pow[MAXN],b[MAXN],ans;
char ch[MAXN];
bool flag;
LL Mul(LL a,LL b,LL P)
{
LL ret=0;
for (;b;b>>=1,a=(a+a)%P) if (b&1) (ret+=a)%=P;
return ret;
}
void Fib(LL n,LL &x,LL &y,LL P)
{
if (!n) { x=0;y=1;return; }
if (n==1) { x=1;y=1;return; }
if (n&1) { Fib(n-1,y,x,P);y=(x+y)%P;return; }
LL a,b;Fib(n>>1,a,b,P);
x=(Mul(a,b,P)+Mul(a,b<a?b-a+P:b-a,P))%P;
y=(Mul(a,a,P)+Mul(b,b,P))%P;
}
void dfs(int n,LL t,LL T)
{
if (flag) return;
LL x,y;Fib(t,x,y,Pow[n]);
if (x!=b[n]) return;
if (n==1) { flag=1;ans=6000000000000000000ull+t;return; }
for (int i=0;i<10;i++) dfs(n-1,(t+T*i)%(T*10),T*10);
}
int main()
{
scanf("%s",ch+1);n=strlen(ch+1);
for (int i=n;i;i--) Pow[i]=(i==n)?1:Pow[i+1]*10,b[i]=Pow[i]*(ch[i]-'0')+b[i+1];
for (int i=1;i<=n;i++) Pow[i]*=10;
for (int i=0;i<60;i++) dfs(n,i,60);
if (flag) cout<<ans<<endl; else puts("NIE");
}