number number number HDU - 6198

2018TYUT暑期ACM模拟赛(3)
number number number HDU - 6198
题意:给出k,问最先找到的不能由 n= fa1+fa2…fak。构成的n是多少。(f(0)=0,f(1)=1,f(2)=1…..f(n)=f(n-1)+f(n-2))
思路:首先暴力打表找出答案的规律。然后用高斯消元找出递推式的系数,最后用矩阵快速幂求出答案。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod=998244353;
struct matrix{
    ll x[3][3];
};
matrix multi(matrix a,matrix b)//矩阵相乘
{
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
            {
                temp.x[i][j]+=a.x[i][k]*b.x[k][j];
                temp.x[i][j]%=mod;//负数取模的问题,除法取模
            }
    return temp;
}
matrix quick_multi(matrix a,ll n)//矩阵快速幂
{
    matrix temp=a;
    n--;
    while(n){
        if(n&1)
            temp=multi(temp,a);
        a=multi(a,a);
        n>>=1;
    }
    return temp;
}int main()
{
    ll k;
    while(cin>>k){
        if(k==1)
        {
            cout<<4<<endl;
            continue;
        }
        if(k==2)
        {
            cout<<12<<endl;
            continue;
        }
        if(k==3)
        {
            cout<<33<<endl;
            continue;
        }
        matrix A;
        matrix ans;
        memset(A.x,0,sizeof(A.x));
        memset(ans.x,0,sizeof(ans.x));
        A.x[0][0]=4;A.x[1][0]=-4;A.x[2][0]=1;//A.x[3][0]=-1;
        A.x[0][1]=1;A.x[1][2]=1;
        ans.x[0][0]=33,ans.x[0][1]=12,ans.x[0][2]=4,//ans.x[0][3]=1;

        A=quick_multi(A,k-3);
        ans=multi(ans,A);
        printf("%lld\n",(ans.x[0][0]+mod)%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/miranda_ymz/article/details/81072543