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;
}
继续加油~