fib数列关于10^x的循环节为6*10^x
关于循环节可以看:http://blog.csdn.net/u014609452/article/details/53039157
然后就可以低位到高位dfs
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
inline ll mul(ll x,ll y,ll p){
ll tmp=(x*y-(ll)((long double)x/p*y+1.0e-8)*p);
return tmp<0?tmp+p:tmp;
}
namespace F{
struct Matrix{
ll a,b,c,d;
Matrix(ll a=0,ll b=0,ll c=0,ll d=0):a(a),b(b),c(c),d(d) { }
};
inline Matrix Mul(Matrix A,Matrix B,ll p){
return Matrix((mul(A.a,B.a,p)+mul(A.b,B.c,p))%p,(mul(A.a,B.b,p)+mul(A.b,B.d,p))%p,(mul(A.c,B.a,p)+mul(A.d,B.c,p))%p,(mul(A.c,B.b,p)+mul(A.d,B.d,p))%p);
}
inline Matrix Pow(Matrix a,ll b,ll p){
Matrix ret(1,0,0,1);
for (;b;b>>=1,a=Mul(a,a,p))
if (b&1)
ret=Mul(ret,a,p);
return ret;
}
inline ll f(ll n,ll p){
if (!n) return 0;
return Pow(Matrix(1,1,1,0),n-1,p).a;
}
}
ll mod[25],num[25];
char str[25];int n;
int flag; ll ans;
void dfs(int n,ll cur,ll T){
if (flag) return;
if (F::f(cur,mod[n])!=num[n]) return;
if (n==1){
flag=1,ans=cur+6000000000000000000ULL;
return;
}
for (int i=0;i<10;i++)
dfs(n-1,(cur+T*i)%(T*10),T*10);
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%s",str+1); int n=strlen(str+1);
mod[n]=1; for (int i=n;i;i--) num[i]=num[i+1]+mod[i]*(str[i]-'0'),mod[i-1]=mod[i]*10;
for (int i=n;i;i--) mod[i]*=10;
for (int i=0;i<60;i++)
if (!flag)
dfs(n,i,60);
flag?printf("%lld\n",ans):printf("NIE\n");
return 0;
}