解析
新定义数位dp了属于是。
结论:斐波拉契在模 10m10^m10m 的意义下循环节为 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_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endiftr.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;
}
/*
*/