hdu 6198 number number number

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=6198

题意:

如果一个数字 n 可以等于k个斐波那契数的和(这些斐波那契数可以相等),那么 n 就称为mifgood,否则就是 mifbad ,当给定 k 时,求最小mifbad数字

思路:

可以推出规律,当 k=1 时,答案为 4 ,当k=2时,可以发现,当首次遇到相邻两个 fib 数字 ai , ai+1 之差大于 4 时,那么第一个mifbad就一定是 ai+4 ,因为 ai+1 , ai+2 , ai+3 都是可以凑出来的,可以发现答案是 8+4=12 ;当 k=3 时,首次遇到相邻两个 fib 数字 ai , ai+1 之差大于 12 时,那么 ai+12 是一定凑不出来的,答案就是 21+12=33 …一直推下去,可以发现 4=51 12=131 33=341 88=891 …答案就是 fib(4+2k1)1 ,用矩阵快速幂求解

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 10 + 10;
const ll mod = 998244353;

struct matrix
{
    int row, col;
    ll mat[N][N];
    matrix(int _row=0, int _col=0)
    {
        init(_row, _col);
    }
    void init(int _row, int _col)
    {
        row = _row, col = _col;
        memset(mat, 0, sizeof mat);
    }
    matrix operator* (matrix b)
    {
        matrix c(row, b.col);
        for(int i = 1; i <= row; i++)
            for(int j = 1; j <= b.col; j++)
                for(int k = 1; k <= col; k++)
                    c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j] % mod) % mod;
        return c;
    }
};
matrix mod_pow(matrix a, ll b, ll p)
{
    matrix ans(2, 2);
    ans.mat[1][1] = ans.mat[2][2] = 1;
    while(b)
    {
        if(b & 1) ans = ans * a;
        a = a * a;
        b >>= 1;
    }
    return ans;
}
int main()
{
    int k;
    while(~ scanf("%d", &k))
    {
        k = 4 + 2*k - 1;
        matrix a(2, 2);
        a.mat[1][1] = 1, a.mat[1][2] = 1;
        a.mat[2][1] = 1, a.mat[2][2] = 0;
        a = mod_pow(a, k, mod);
        printf("%lld\n", a.mat[1][2] - 1);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值