【PA2015】【BZOJ4294】Fibonacci

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");
}

你可能感兴趣的:(数学,爆搜,Fib数列的性质)