HDU-6198 number number number(打表找规律、矩阵快速幂)

来源:互联网 发布:叉叉助手脚本提取源码 编辑:程序博客网 时间:2024/06/08 10:42

2017 ACM/ICPC Asia Regional Shenyang Online

题意:

给定一个k,恰好能通过k个斐波那契数相加的数称作mjf-good,否则称作mjf-bad,给定k求值最小的mjf-bad数。[斐波那契数列从f[0]=0,f[1]=1开始]

思路:

由于0也属于斐波那契数,那么mjf-good就转化为了至少能通过k个斐波那契数相加的数,通过打表发现每个k不同的最小的mjf-bad数都是由一个斐波那契数-1所得。然后发现这若干个斐波那契数满足F[n] = F[n-1]*3-F[n-2]; 从而进行矩阵快速幂求解即可。

代码:

#include <algorithm>    #include <string.h>    #include <cstdio>      #define LL long long      using namespace std;      const LL mod = 998244353;  struct node{ LL m[2][2];};node multi(node x, node y)    {        node res = {0, 0, 0, 0};    for(int i = 0; i < 2; ++i)        for(int j = 0; j < 2; ++j)        for(int k = 0; k < 2; ++k)            res.m[i][j] += x.m[i][k]*y.m[k][j], res.m[i][j] = (res.m[i][j]+mod)%mod;        return res;    }    LL qpow(LL n)    {        node ans = {1, 0,                     0, 1};        node bas = {3, -1,                   1, 0};        node col = {5, 0,                   2, 0};        while(n)        {            if(n&1) ans = multi(ans, bas);            bas = multi(bas, bas);            n >>= 1;        }        return (multi(ans, col).m[0][0]-1+mod)%mod;    }     int main()      {    int k;     while(~scanf("%d", &k)) printf("%lld\n", qpow(k-1));    return 0;      }


继续加油~

原创粉丝点击