hdu number number number 斐波那契数列 思维

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

F0=0,F1=1的斐波那契数列。

给定K,问最小的不能被k个数组合而成的数是什么。

赛后才突然醒悟,只要间隔着取k+1个数,显然根据斐波那契数列规律是不存在把其中两个数相加的结果又出现在数列中的情况(有特别的看下面),不就不会被组合出来了么?

这里有1 3 8...这种和1 2 5 13...两种,但因为后者任意一位的1,2可以被转化为3,这是唯一一种特例,所以我们采用前者。构造矩阵快速幂一下。

#include <cstdio>
#include <string>
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define LL long long
using namespace std;
const LL N = 1000006;
const LL mod = 998244353;
LL n;
struct mx
{
    LL n, m;
    LL c[4][4];//需要根据题目开大
    void initMath(LL _n)//初始化方阵
    {
        m = n = _n;
    }
    void initOne(LL _n)//初始化单位矩阵
    {
        m = n = _n;
        for (LL i = 0; i<n; i++)
            for (LL j = 0; j<m; j++)
                c[i][j] = (i == j);
    }
    void print()//测试打印
    {
        for (LL i = 0; i<n; i++)
        {
            for (LL j = 0; j<m; j++)
                cout << c[i][j] << ' ';
            cout << endl;
        }
    }
};
mx Mut(mx a, mx b)
{
    mx c;
    c.n = a.n, c.m = b.m;
    for (LL i = 0; i<a.n; i++)
        for (LL j = 0; j<b.m; j++)
        {
            LL sum = 0;
            for (LL k = 0; k<b.n; k++)
                sum += a.c[i][k] * b.c[k][j], sum %= mod;
            c.c[i][j] = sum;
        }
    return c;
}
mx fastMi(mx a, LL b)
{
    mx mut; mut.initOne(a.n);
    while (b)
    {
        if (b % 2 != 0)
            mut = Mut(mut, a);
        a = Mut(a, a);
        b /= 2;
    }
    return mut;
}
int main()
{
    cin.sync_with_stdio(false);
    LL m;
    while (cin>>m>>n)
    {
        if (n == 0)cout << 0 << endl;
        else if (n == 1)
        {
            cout << m << endl;
        }
        else
        {
            cout << n * (m - n) + n << endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/LukeStepByStep/p/7502524.html