hdu6198(矩阵快速幂+找规律)

We define a sequence  F:

  F0=0,F1=1;
  Fn=Fn1+Fn2 (n2).

Give you an integer  k, if a positive number  n can be expressed by
n=Fa1+Fa2+...+Fak where  0a1a2ak, this positive number is  mjfgood. Otherwise, this positive number is  mjfbad.
Now, give you an integer  k, you task is to find the minimal positive  mjfbad 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. ( 1k109)
 

Output
For each case, output the minimal  mjfbad number mod 998244353.
 

Sample Input
 
   
1
 

Sample Output
 
   
4
题意:求不能由k个fib数组成的最小整数。
思路:先推出前5项,F[0]=1,F[1]=4,F[2]=12,F[3]=33,F[4]=88;然后就找出规律F[i]=F[i-1]*3-F[i-2]+1;得到递推式子这就很简单了,由于k很大,矩直接阵快速幂。
代码:
#include
using namespace std;
typedef long long LL;
const int mod=998244353;
const int maxn=3;
struct Matrix
{
    LL temp[maxn][maxn];
}a;
void init()
{
    for(int i=0;i<maxn;i++)
    {
        for(int j=0;j<maxn;j++)
        {
            a.temp[i][j]=0;
        }
    }
    a.temp[0][0]=3,a.temp[0][1]=-1;
    a.temp[1][0]=a.temp[2][2]=a.temp[0][2]=1;//系数
}
Matrix mul(Matrix a,Matrix b)
{
    Matrix ans;
    for(int i=0;i<maxn;i++)
    {
        for(int j=0;j<maxn;j++)
        {
            ans.temp[i][j]=0;
            for(int k=0;k<maxn;k++)
            {
                ans.temp[i][j]+=(a.temp[i][k]*b.temp[k][j]+mod)%mod;
                ans.temp[i][j]%=mod;
            }
        }
    }
    return ans;
}
void pow(Matrix ans,LL k)
{
    memset(a.temp,0,sizeof(a.temp));
    for(int i=0;i<maxn;i++) a.temp[i][i]=1;
    while(k)
    {
        if(k&1) a=mul(a,ans);
        ans=mul(ans,ans);
        k>>=1;
    }
}
int main()
{
    Matrix t;
    LL n;
    for(int i=0;i<maxn;i++)
    {
        for(int j=0;j<maxn;j++)
        {
            t.temp[i][j]=0;
        }
    }
    t.temp[0][0]=12,t.temp[1][0]=4;
    t.temp[2][0]=1;//前几项值
    while(scanf("%lld",&n)!=EOF)
    {
        init();
        if(n<=2)
        {
            printf("%lld\n",t.temp[2-n][0]);
            continue;
        }
        pow(a,n-2);
        a=mul(a,t);
        LL ans=a.temp[0][0]%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(矩阵快速幂)