题意:
给你一个斐波那契数列,和一个k,能被k个斐波那契数(可重复)正好相加的数为good,否则为bad。在给定的k的前提下,让你求最小的bad数。
思路:
在稿纸上写个斐波那契数列,并推出前几个k的答案,发现所求值为第k*2+3项斐波那契数减1。然后用矩阵快速幂求斐波那契数即可。(((自己手写的矩阵快速幂渣爆了,copy了大腿的模板。。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
struct matrix
{
int r, c;
ll m[4][4];
matrix(){memset(m,0,sizeof m);}
matrix(int r, int c):r(r),c(c){ memset(m,0,sizeof m);}
matrix operator*(const matrix& b){
matrix temp(r, b.c);
for(int i=0; i<r; i++)
for(int j=0; j<b.c; j++){
for(int k=0; k<c; k++)
temp.m[i][j] = (temp.m[i][j]+m[i][k]*b.m[k][j])%mod;
}
return temp;
}
//warning: only square matrix can use this function
matrix pow(ll n){
matrix a =*this;
matrix temp(c,c);
for(int i=0; i<temp.c; i++)
temp.m[i][i] = 1;
while(n){
if(n&1) temp = temp*a;
a = a*a;
n>>=1;
}
return temp;
}
void show(){
for(int i=0; i<r; i++){
for(int j=0; j<c; j++)
cout<<setw(4)<<m[i][j];
cout<<endl;
}
}
};
int main()
{
matrix a(2,2);
matrix b(2,2);
a.m[0][0] = a.m[0][1] = a.m[1][0] = 1;
ll k;
while(~scanf("%lld",&k))
{
b = a.pow(k*2+3);
printf("%lld\n",b.m[1][0]-1);
}
return 0;
}