number number number hdu 6189 矩阵快速幂

来源:互联网 发布:android studio 源码 编辑:程序博客网 时间:2024/06/07 05:17

题目链接


We define a sequence F:⋅ F0=0,F1=1;⋅ Fn=Fn−1+Fn−2 (n≥2).Give you an integer k, if a positive number n can be expressed byn=Fa1+Fa2+...+Fak where 0≤a1≤a2≤⋯≤ak, this positive number is mjf−good. Otherwise, this positive number is mjf−bad.Now, give you an integer k, you task is to find the minimal positive mjf−bad number.The answer may be too large. Please print the answer modulo 998244353.

Input

There are about 500 test cases, end up with EOF.Each test case includes an integer k which is described above. (1≤k≤109)

Output

For each case, output the minimal mjf−bad number mod 998244353.

Sample Input

1

Sample Output

4

Source

2017 ACM/ICPC Asia Regional Shenyang Online 

题意:

给你一个 k, 计算不能用 k 个可以重复的斐波那契数列组成的最小的数.

思路:

打表找规律, 我们发现k = 1 时, 答案为 F51, (F为斐波那契数列), k = 2 时, 答案为 F71, k = 3 时, 答案为 F91, 验证一下发现k = 4 时答案也成立, 然后就是矩阵快速幂,

其实我觉得是可以证明的, 但是鶸表示不会, 我的猜测大概思路应该是因为k = 1 时候, 答案为 4, 然后k = 2 时的答案一定由4 加上某个数组成, 然后要使这个数最小, 所以找一个比 4 大, 而且不为 5 的最小的斐波那契数, 所以 k = 2的答案应该是 4 + 8, 就等于F71 依次类推,—博主不敢保证思路正确, 若有人会证明请告诉博主.

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;typedef long long LL;const int mod = 998244353;LL k;struct mat {    LL a[3][3];    mat(){memset(a, 0,sizeof(a)); }    mat operator *(const mat q){        mat c;        for(int i = 1; i <= 2; ++i)            for(int j = 1; j <= 2; ++j)            if(a[i][j])        for(int k = 1;  k<= 2; ++k){            c.a[i][k] += a[i][j] * q.a[j][k];            c.a[i][k] %= mod;        }return c;    }};mat qpow(mat x, LL n){    mat ans;    ans.a[1][1] = ans.a[2][2] = 1;    while(n){        if(n&1) ans = ans * x;        x = x * x;        n >>= 1;    }return ans;}LL qpow(LL x,LL n){    LL ans = 1;    while(n){        if (n&1) ans = (ans * x) %( mod + 1);        x = (x * x) % (mod + 1);        n >>= 1;    }return ans;}int main(){    mat tmp, ans;    tmp.a[1][1] = tmp.a[1][2] = tmp.a[2][1] = 1;    while(scanf("%lld", &k) != EOF){        ans = qpow(tmp, 2 * k + 3);        printf("%lld\n",(((ans.a[2][1] -1) % mod) + mod) % mod);    }return 0;}
原创粉丝点击