暂无连接
第一题
【问题描述】
斐波那契数列满足 f[0]=0,f[1]=1,f[i]=f[i−1]+f[i−2](i>=2) f [ 0 ] = 0 , f [ 1 ] = 1 , f [ i ] = f [ i − 1 ] + f [ i − 2 ] ( i >= 2 ) 。已知 f[i] f [ i ] 对 1013 10 13 取模的结果 k k ,求最小的可能的 。无解输出 −1 − 1 。
【输入格式】
输入包含一个非负整数 k k 。
【输出格式】
输出一个整数,为最小的可能的 。无解输出 −1 − 1 。
【输入样例 1】
17711
【输出样例 1】
22
【输入样例 2】
7
【输出样例 2】
9366795780274
【数据范围】
前三个数据点的 k k 分别为 。
对于 100% 100 % 的数据点, 0<=k<1013 0 <= k < 10 13 。
题解
又双叕TM是打表找规律。。。
当然你可以去找网上的证明。
话说这个部分分真TM不良心,直接 O(n) O ( n ) 推,考试结束都没出来。。。
打个大表,你会发现 mod 10 m o d 10 的循环节是 60 60 , mod 100 m o d 100 是 300 300 , mod 1000 m o d 1000 是 1500 1500 , ⋯ ⋯ , mod 10n m o d 10 n 是 1.5×10n 1.5 × 10 n 。下一层循环节是上一层的因数,而且循环节大小是线性的,所以我们可以一位一位的满足 k k 。
在跳循环节的时候,我们还需要验证当前项是否满足要求,需要矩阵加速递推数列,而且还需要慢速乘,真是恶心。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e13;
ll loop[15],k;
struct matrix{ll sq[3][3];matrix(){memset(sq,0,sizeof(sq));}}mat,one;
vector<ll>yeah[15];
ll X(ll x,ll p){ll ans=0;for(;p;p>>=1,(x<<=1)%=mod)if(p&1)(ans+=x)%=mod;return ans;}
matrix operator *(matrix a,matrix b)
{
matrix c;
c.sq[1][1]=(X(a.sq[1][1],b.sq[1][1])+X(a.sq[1][2],b.sq[2][1]))%mod;
c.sq[1][2]=(X(a.sq[1][1],b.sq[1][2])+X(a.sq[1][2],b.sq[2][2]))%mod;
c.sq[2][1]=(X(a.sq[2][1],b.sq[1][1])+X(a.sq[2][2],b.sq[2][1]))%mod;
c.sq[2][2]=(X(a.sq[2][1],b.sq[1][2])+X(a.sq[2][2],b.sq[2][2]))%mod;
return c;
}
matrix power(matrix x,ll p){matrix ans=one;for(;p;p>>=1,x=x*x)if(p&1)ans=ans*x;return ans;}
void in(){scanf("%lld",&k);}
void ac()
{
int a;ll mod=10,pos,now,ans=LONG_LONG_MAX;bool flag=0;
one.sq[1][1]=one.sq[2][2]=1;
mat.sq[1][1]=mat.sq[1][2]=mat.sq[2][1]=1;
loop[0]=1,loop[1]=60,loop[2]=300;
yeah[0].push_back(1);
for(ll i=3,x=1500;i<=13;++i,x*=10)loop[i]=x;
for(int p=1;p<=13;++p,mod*=10,flag=0)
{
for(int i=yeah[p-1].size()-1;i>=0;--i)
{
pos=yeah[p-1][i];
for(ll j=0;j<loop[p];j+=loop[p-1])
{now=power(mat,pos+j-1).sq[1][1];if(now%mod==k%mod){flag=1;yeah[p].push_back(pos+j);}}
}
if(!flag)puts("-1"),exit(0);
}
for(int i=yeah[13].size()-1;i>=0;--i)ans=min(ans,yeah[13][i]);
printf("%lld",ans);
}
int main(){in();ac();}