阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。 他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为 0
标签:考试 字符 lin 方案 scanf mat print scan 准备
阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。 他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为 0
第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.
#include <cstdio> #include <cstring> const int maxm = 25; int mod; struct matrix{ int n, m, num[maxm][maxm]; matrix(){} matrix(int _n, int _m){ n = _n; m = _m; memset(num, 0, sizeof num); } matrix operator * (const matrix &a){ matrix b(n, a.m); for(int i = 0; i < n; i++) for(int j = 0; j < a.m; j++) for(int k = 0; k < m; k++) (b.num[i][j] += num[i][k] * a.num[k][j]) %= mod; return b; } }; matrix ksm(matrix a, int b){ matrix s(a.m, a.m); for(int i = 0; i < s.m; i++) s.num[i][i] = 1; while(b){ if(b & 1) s = s * a; b >>= 1; a = a * a; } return s; } int n, m; char A[maxm]; int p[maxm]; int main(){ scanf("%d %d %d", &n, &m, &mod); scanf("%s", A + 1); p[1] = 0; for(int j = 0, i = 2; i <= m; i++){ while(A[i] != A[j + 1] && j) j = p[j]; if(A[i] == A[j + 1]) j++; p[i] = j; } matrix ans(1, m), zy(m, m); for(int i = 0; i < m; i++) for(int j = ‘0‘; j <= ‘9‘; j++){ int k = i; while(k && A[k + 1] != j) k = p[k]; if(A[k + 1] == j) k++; if(k != m) zy.num[i][k]++; } ans.num[0][0] = 1; ans = ans * ksm(zy, n); int aa = 0; for(int i = 0; i < m; i++) (aa += ans.num[0][i]) %= mod; printf("%d\n", aa); return 0; }
标签:考试 字符 lin 方案 scanf mat print scan 准备
原文地址:http://www.cnblogs.com/ruoruoruo/p/7440350.html