解析
新定义数位dp了属于是。
结论:斐波拉契在模 1 0 m 10^m 10m 的意义下循环节为 6*10^m。
但这个不一定是最小循环节,我自己做的时候打表得出来的循环节更小。
考虑从低到高枚举周期中的位置,暴力check合法进行剪枝。
跑的飞快,O(能过)。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ldb long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Ok debug("OK\n")
using namespace std;
const int N=2e5+100;
const int inf=1e9;
//const int mod=998244353
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
/*
inline ll ksm(ll x,ll k){
ll res(1);
while(k){
if(k&1) res=res*x%mod;
x=x*x%mod;
k>>=1;
}
return res;
}*/
inline ull qm(ull x,ull y,ull mod){
ll r=(ldb)x*y/mod+0.5,res=x*y-mod*r;
return res<0?res+mod:res;
}
struct matrix{
int x,y;
ull a[3][3];
matrix(int X,int Y):x(X),y(Y){memset(a,0,sizeof(a));}
}tr(2,2),I(2,2);
matrix mul(const matrix &u,const matrix &v,ull mod){
matrix res(u.x,v.y);
for(int k=1;k<=u.y;k++){
for(int i=1;i<=u.x;i++){
ull tmp=u.a[i][k];
for(int j=1;j<=v.y;j++){
res.a[i][j]=(res.a[i][j]+qm(tmp,v.a[k][j],mod))%mod;
}
}
}
return res;
}
matrix ksm(matrix x,ull k,ull mod){
matrix ans=I;
while(k){
if(k&1) ans=mul(ans,x,mod);
x=mul(x,x,mod);
k>>=1;
}
return ans;
}
inline ull Fib(int n,ull mod){
if(n<=0) return 0;
matrix res(1,2);
res.a[1][1]=0;
res.a[1][2]=1;
res=mul(res,ksm(tr,n,mod),mod);
return res.a[1][1];
}
int n;
ull mi[20],a[20];
int top;
void dfs(int k,ull n,ull len){
//printf("k=%d n=%llu Fib=%llu\n",k,n,Fib(n,mi[k]));
if(Fib(n,mi[k])!=a[k]) return;
if(k==top){
//n+=6*mi[18];
//printf("top=%d Fib=%lld %lld\n",top,Fib(n,mi[k]),a[k]);
printf("%llu\n",n);exit(0);
}
for(int i=0;i<10;i++){
dfs(k+1,(n+qm(i,len,len*10)%(len*10)),len*10);
}
return;
}
inline int calc(ull x){
int res(0);
while(x){
++res;x/=10;
}
return res;
}
char s[50];
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
tr.a[1][1]=0;tr.a[1][2]=1;
tr.a[2][1]=1;tr.a[2][2]=1;
I.a[1][1]=I.a[2][2]=1;
//for(int i=1;i<=10;i++) printf("%lld\n",Fib(i,998244353));
scanf(" %s",s+1);top=strlen(s+1);
mi[0]=1;
for(int i=1;i<=18;i++) mi[i]=mi[i-1]*10;
for(int i=1;i<=top;i++) a[i]=a[i-1]+(s[top-i+1]-'0')*mi[i-1];
//for(int i=1;i<=top;i++) printf("i=%d top=%llu\n",i,a[i]);
for(int i=1;i<=60;i++) dfs(1,i,60);
puts("NIE");
return 0;
}
/*
*/