矩阵快速幂-1246

题目大意:

矩阵快速幂-1246

 

思路:

  看到这么高的数据复杂度肯定要log级别的算法才可以过,所以肯定有递推公式,我们可以从一个数字递推一下看当前数字可以转移到哪几个数字,很容易发现出现了一个递推矩阵,再看2个数字的情况,也是一样的,但是要注意不要重复判定就行,就比如4-16-26-46-66-46这样就会出现环,出现环就结束就行了,所以也可以写出2个数字的递推式,所以就可以构造一个递推矩阵。能水过96分,但是大于等于3的情况比较多,先记录一下,以后推出来补充

代码:

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
int v2id[70];
int b_e[]={1,2,4,6,16,26,41,42,44,46,61,62,64,66};
int f_t[][4]={{2},{4},{1,6,16},{6,4,64},{26},{46},{62},{64},{61},{66},{42},{44},{41},{46}};
const int mod=998244353;
vector<vector<ll>> mul(vector<vector<ll>> a,vector<vector<ll>> b){
    int n=a.size();
    int kk=a[0].size();
    int m=b[0].size();
    vector<vector<ll>> res(n,vector<ll>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            for(int k=0;k<kk;k++){
                res[i][j]+=((a[i][k]*1ll*b[k][j])%mod);
                res[i][j]=res[i][j]%mod;
            }
        }
    }
    return res;
}

vector<vector<ll>> qmi(vector<vector<ll>> a,int n){
    int r=a.size();
    vector<vector<ll>> res(1,vector<ll>(r,0));
    res[0][0]=1;//把2置为1表示第一个状态 然后快速幂就行了
    
    while(n){
        if(n&1)res=mul(res,a);
        a=mul(a,a);
        n>>=1;
    }
    return res;
}


ll slove(int id,int n){
    vector<vector<ll>> a(14,vector<ll>(14,0));
    for(int i=0;i<14;i++){
        for(int j=0;j<=3;j++){
            if(f_t[i][j]==0)break;
            a[i][v2id[f_t[i][j]]]++;
        }
    }
    vector<vector<ll>> res=qmi(a,n);
    return res[0][id]%mod;
}

int main(){
    memset(v2id,-1,sizeof v2id);
    for(int i=0;i<14;i++){
        v2id[b_e[i]]=i;
    }
    int n;
    string s;
    cin>>n>>s;
    int num=0;
    for(int i=0;i<s.size();i++){
        num*=10;
        num+=(s[i]-'0');
    }
    if(s.size()<=2)cout<<slove(v2id[num],n)<<endl;
    else {
        // 还有一个测试样例不知道咋搞递推式
    }
}

 

上一篇:法语口语渐进中级 笔记 草稿


下一篇:面试题46:把数字翻译成字符串