1. 程式人生 > >hdu6198 number number number(找規律+矩陣快速冪)

hdu6198 number number number(找規律+矩陣快速冪)

Problem Description

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 by
n=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≤10^9)

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

Sample Input
1

Sample Output
4

大致題意:如果從斐波那契數列中任選k個數相加(可重複選),都不能得到某個數,則稱這個數為壞數,現在告訴你k的值,讓你找出最小的壞數。

思路:暴力地去求下前幾種情況,可以發現當k=1時,答案為5-1=4,當k=2時答案為13-1=12,當k=3時,答案為34-1=33。。。假設5為斐波那契數列的第一項,8為第二項,f(x)表示第x項斐波那契的值,那麼答案為f(2*k-1)-1。然後用矩陣快速冪去求第2*k-1項斐波那契數列的值。

程式碼如下

#include <iostream> 
#include <cstring>
#include <cstdio>
using namespace std; 
#define LL long long 
const int mod= 998244353
; struct matrix { LL x[2][2]; }; matrix mutimatrix(matrix a,matrix b) { matrix temp; memset(temp.x,0,sizeof(temp.x)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) { temp.x[i][j]+=a.x[i][k]*b.x[k][j]; temp.x[i][j]%=mod; } return temp; } matrix k_powmatrix(matrix a,LL n)//矩陣快速冪 { matrix temp; memset(temp.x,0,sizeof(temp.x)); for(int i=0;i<2;i++) temp.x[i][i]=1; while(n) { if(n&1) temp=mutimatrix(temp,a); a=mutimatrix(a,a); n>>=1; } return temp; } int main() { LL k; while(scanf("%lld",&k)!=EOF) { matrix st; //memset(st.x,0,sizeof(st.x)); st.x[0][0]=1; st.x[0][1]=1; st.x[1][0]=1; st.x[1][1]=0; matrix init;//初始矩陣 //memset(init.x,0,sizeof(init.x)); init.x[0][0]=8; init.x[0][1]=5; st=k_powmatrix(st,2*(k-1)); st=mutimatrix(init,st);//然後再乘上初始矩陣 printf("%lld\n",(st.x[0][1]-1+mod)%mod); } return 0; }