HDU 6198 number number number(矩阵快速幂)

本文探讨了由特定数量的斐波那契数组合无法构成的最小正整数问题,并提供了一种通过矩阵快速幂求解的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

问不能由kk个斐波那契数组成的最小正整数

Input

多组用例,每组用例输入一整数k(1k109)

Output

对于每组用例,输出答案,结果模998244353998244353

Sample Input

1

Sample Output

4

Solution

k=1k=1时,答案为4=f(5)14=f(5)−1k=2k=2时,答案为12=f(7)112=f(7)−1,假设不能由ii个斐波那契数组成的最小正整数为f(2i+3)1,i2,下面证明不能由i+1i+1个斐波那契数组成的最小正整数为f(2i+5)1f(2i+5)−1

首先证明,i+1i+1个斐波那契数可以组成00~f(2i+5)2中的每个数字xx

1.0xf(2i+3)2,取第i+1i+1个斐波那契数为f(0)=0f(0)=0,前ii个数字可以组成0~f(2i+3)2f(2i+3)−2中每个数字

2.f(2i+3)1xf(2i+4)2f(2i+3)−1≤x≤f(2i+4)−2,取第i+1i+1个斐波那契数为f(2i+2)f(2i+2),由于前ii个数字可以组成0~f(2i+3)2f(2i+3)−2,故这i+1i+1个数字可以组成f(2i+2)f(2i+2)~f(2i+4)2f(2i+4)−2,而i2i≥2f(2i+2)<f(2i+3)1f(2i+2)<f(2i+3)−1

3.x=f(2i+4)1x=f(2i+4)−1,取第i+1i+1个斐波那契数为f(2i+3)f(2i+3),由f(2i+1)>1f(2i+1)>1f(2i+2)1<f(2i+3)2f(2i+2)−1<f(2i+3)−2,故前ii个数可以表示出xf(2i+3)=f(2i+2)1

4.f(2i+4)xf(2i+5)2f(2i+4)≤x≤f(2i+5)−2,取第i+1i+1个斐波那契数为f(2i+4)f(2i+4)即可

然后证明,i+1i+1个斐波那契数不能组成f(2i+5)1f(2i+5)−1,假设第i+1i+1个斐波那契数为f(x)f(x),显然0x2i+40≤x≤2i+4,而xf(x)f(2i+5)1f(2i+4)=f(2i+3)1x−f(x)≥f(2i+5)−1−f(2i+4)=f(2i+3)−1,前ii个数组不成f(2i+3)1,故i+1i+1个斐波那契数组不成f(2i+5)1f(2i+5)−1

综上,kk个斐波那契数组不成的最小正整数为f(2k+3)1,用矩阵快速幂求解即可

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
#define mod 998244353
typedef ll Mat[2][2];
void Mul(Mat &A,Mat B)
{
    Mat C;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {
            C[i][j]=0;
            for(int k=0;k<2;k++)C[i][j]+=A[i][k]*B[k][j];
        }
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            A[i][j]=C[i][j]%mod;
}
void Pow(Mat &A,int k)
{
    Mat B={{1,0},{0,1}};
    while(k)
    {
        if(k&1)Mul(B,A);
        Mul(A,A);
        k>>=1;
    }
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            A[i][j]=B[i][j];
}
int main()
{
    int k;
    while(~scanf("%d",&k))
    {
        Mat A={{1,1},{1,0}};
        Pow(A,2*k+2);
        printf("%I64d\n",(A[0][0]+mod-1)%mod);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值