题意:给定斐波那契数列:
0,1,1,2,3,5,8,13,21,34,55……
输入一个数字k,求k个斐波那契数列中的数不能组成的最小的数字,其中k个数可以重复,比如k=1,那么1个斐波那契数列中不能组成的最小的数字为4,结果再对一个素数取余
思路:思路比较简单..归纳找规律..
多写几组数据来找一下规律:
若k=2,注意2=1+1,我们知道1个数字0-3都可以找到,依次加到序列上,那么1-4、2-5、3-6、5-8、8-11、13-16都可以找到,这里就发现了12不能,所以2的结果是12
若k=3,同理,可以发现12+21=33不能被找到
若k=4,结果为88
这样就可以发现一个规律,ans=F(2*k+3)-1,即第2*k+3个斐波那契数列的数减1,求斐波那契数列用了矩阵快速幂
完整代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int mod=998244353;
const int N=2;
struct matrix
{
LL m[N][N];
};
matrix matrixmul(matrix a,matrix b)
{
LL i,j,k;
matrix c;
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
c.m[i][j]=0;
for(k=0;k<N;k++)
{
c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
}
c.m[i][j]=c.m[i][j]%mod;
}
}
return c;
}
matrix quickpow(LL n)
{
matrix m={1,1,1,0};
matrix c={1,0,0,1};
while(n>=1)
{
if(n&1)
{
c=matrixmul(c,m);
}
n=n>>1;
m=matrixmul(m,m);
}
return c;
}
int main()
{
LL k;
while(scanf("%lld",&k)!=-1)
{
LL ans;
matrix res=quickpow(2*k+2);
ans=(res.m[0][0]-1)%mod;
printf("%lld\n",ans);
}
return 0;
}