zoukankan      html  css  js  c++  java
  • BZOJ1009: [HNOI2008]GT考试 (矩阵快速幂 + DP)

    题意:求一个长度为n的数字字符串 (n <= 1e9)

       不出现子串s的方案数

    题解:用f i,j表示长度为i匹配到在子串j的答案

       用kmp的失配函数预处理一下 然后这个转移每一个都是一样的 所以可以用矩阵加速

    #include <bits/stdc++.h>
    using namespace std;
    
    int n, m, mod;
    char s[25];
    int fail[25];
    
    struct node {
        int c[25][25];
    }a, re;
    
    node mul(node x, node y) {
        node res;
        memset(res.c, 0, sizeof(res.c));
    
        for(int i = 0; i < m; i++)
        for(int j = 0; j < m; j++)
        for(int k = 0; k < m; k++)
            res.c[i][j] = (res.c[i][j] + x.c[i][k] * y.c[k][j] % mod) % mod;
        return res;
    }
    
    node pow_mod(node x, int y) {
        node res;
        memset(res.c, 0, sizeof(res.c));
        for(int i = 0; i < m; i++) res.c[i][i] = 1;
    
        while(y) {
            if(y & 1) res = mul(res, x);
            x = mul(x, x);
            y >>= 1;
        }
        return res;
    }
    
    int main() {
        scanf("%d%d%d", &n, &m, &mod);
        scanf("%s", s + 1);
    
        fail[1] = fail[2] = 0;
        for(int i = 2; i <= m; i++) {
            int j = fail[i - 1];
            while(j && s[i] != s[j + 1]) j = fail[j];
            fail[i] = s[i] == s[j + 1] ? j + 1 : 0;
        }
    
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < 10; j++) {
                int k = i;
                while(k && (s[k + 1] - '0') != j) k = fail[k];
                if(s[k + 1] - '0' == j) k++;
                if(k != m) a.c[i][k] = (a.c[i][k] + 1) % mod;
            }
        }
    
        re = pow_mod(a, n);
        int ans = 0;
        for(int i = 0; i < m; i++) ans = (ans + re.c[0][i]) % mod;
        
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    AT SELECTIONSCREEN的用法
    ADD的用法
    ~的用法
    DIV+CSS布局
    CSS 列表
    CSS 文本
    VC include 路径解析
    CRITICAL_SECTION临界区学习
    UI设计时要注意的几个方面
    使用和扩展marshal_as库
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11082109.html
Copyright © 2011-2022 走看看