bzoj1009: [HNOI2008]GT考试
马
题解传送门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; }
原文出处http://www.cnblogs.com/showson/