zoukankan      html  css  js  c++  java
  • [HNOI2008] GT考试

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=1009

    [算法]

             首先用kmp预处理最长的后缀 = 前缀

             然后 , 用Fi,j表示前i位 , 匹配j位的方案数

             矩阵优化即可

             时间复杂度 : O(M ^ 3logN)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 25;
    
    int n , m , P;
    int nxt[N];
    int a[N][N] , b[N][N];
    char s[N];
    
    template <typename T> inline void update(T &x , T y)
    {
        x += y;
        x %= P;
    }
    inline void multipy(int a[N][N] , int b[N][N])
    {
        static int ret[N][N];
        memset(ret , 0 , sizeof(ret));
        for (int i = 0; i < m; i++)    
        {
            for (int j = 0; j < m; j++)
            {
                for (int k = 0; k < m; k++)
                {
                    ret[i][j] = (ret[i][j] + 1LL * a[i][k] * b[k][j] % P) % P;
                }
            }
        }
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < m; j++)
            {
                a[i][j] = ret[i][j];
            }
        }
    }
    
    int main()
    {
        
        scanf("%d%d%d" , &n , &m , &P);
        scanf("%s" , s + 1);
        nxt[1] = 0;
        for (int i = 2; i <= m; i++)
        {
            int tmp = nxt[i - 1];
            while (tmp > 0 && s[tmp + 1] != s[i]) tmp = nxt[tmp];
            if (s[tmp + 1] == s[i]) ++tmp;
            nxt[i] = tmp;    
        }
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j <= 9; j++)
            {
                int tmp = i;
                while (tmp > 0 && s[tmp + 1] - '0' != j) tmp = nxt[tmp];
                if (s[tmp + 1] - '0' == j) ++tmp;
                if (tmp != m) update(b[tmp][i] , 1);     
            }    
        }
        for (int i = 0; i < m; i++) a[i][i] = 1;
        while (n > 0)
        {
            if (n & 1) multipy(a , b);
            multipy(b , b);
            n >>= 1;
        }
        int ans = 0;
        for (int i = 0; i < m; i++) update(ans , a[i][0]);
        printf("%d
    " , ans);
        
        return 0;
        
    }
  • 相关阅读:
    SqQueue(环状队列(顺序表结构))
    LinkQueue(链队列)
    CharMatch(括号匹配)
    LinkStack
    x-boot
    安装npm及cnpm(Windows)
    sourcetree跳过注册的方法
    Mysql 5.7 CentOS 7 安装MHA
    ORA-12519 ORA-12516
    lisp : set 与setq 函数
  • 原文地址:https://www.cnblogs.com/evenbao/p/10078754.html
Copyright © 2011-2022 走看看