码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1009: [HNOI2008]GT考试

时间:2015-12-21 21:55:35      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

题解传送门http://www.cnblogs.com/Tunix/p/4412201.html

 

技术分享
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>

using namespace std;

void setIO(const string& s) {
    freopen((s + ".in").c_str(), "r", stdin);
    freopen((s + ".out").c_str(), "w", stdout);
}
template<typename Q> Q read(Q& x) {
    static char c, f;
    for(f = 0; c = getchar(), !isdigit(c); ) if(c == -) f = 1;
    for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - 0;
    if(f) x = -x;
    return x;
}
template<typename Q> Q read() {
    static Q x; read(x); return x;
}

const int N = 20 + 5;

int n, m, p;

template<typename Q> void addit(Q& x, const Q& y) {
    if((x += y) >= p) x -= p;
}

struct Matrix {
    int da[N][N];
    
    void clear() {
        memset(da, 0, sizeof da);
    }
    
    Matrix operator * (const Matrix& b) const {
        static Matrix c;
        c.clear();
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < m; j++){
                for(int k = 0; k < m; k++){
                    addit(c.da[i][j], da[i][k] * b.da[k][j] % p);
                }
            }
        }
        return c;
    }
}A, B;

char s[N];
int fail[N];

void kmp() {
    for(int j = 0, i = 2; i <= m; i++) {
        while(j && s[i] != s[j+1]) j = fail[j];
        if(s[i] == s[j+1]) j++;
        fail[i] = j;
    }
}

void getMatrixB() {
    for(int i = 0; i < m; i++) {
        for(int j = 0; j <= 9; j++) {
            int k = i;
            while(k && s[k+1] != j + 0) k = fail[k];
            if(s[k+1] == j + 0) ++k; 
            ++B.da[i][k];
        }
    }
}

Matrix qpow(Matrix a, int b) {
    Matrix c = a;
    for(b--; ; a = a * a) {
        if(b & 1) c = c * a;
        if(!(b >>= 1)) return c;
    }
}

int main() {
#ifdef DEBUG
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    
    scanf("%d%d%d", &n, &m, &p);
    scanf("%s", s + 1);
    
    kmp();
    getMatrixB();
    A.da[0][0] = 1;
    B = qpow(B, n);
    A = A * B;
    int res = 0;
    for(int i = 0; i < m; i++) {
        addit(res, B.da[0][i]);
    }
    printf("%d\n", res);
    
    return 0;
}
View Code

 

bzoj1009: [HNOI2008]GT考试

标签:

原文地址:http://www.cnblogs.com/showson/p/5064780.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!