BZOJ1009:[HNOI2008]GT考试——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1009
Description
阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0Input
第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000
Output
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.
Sample Input
4 3 100
111Sample Output
81
参考:http://hzwer.com/2955.html 和 https://www.geek-share.com/detail/2632945401.html
有一个很显然的dp,设f[i][j]表示j长度的准考证号的[j-i+1,j]正好与不吉利串的[1,i]匹配上(同时准考证号没有出现过不吉利串)。
我们显然要求的是f[0]
+f[1]
+f[2]
……+f[m-1]
显然n太大了,我们需要对此优化。
考虑到f[i][j]=sigma(f[k][j-1])(通过枚举尾部放哪个字符来决定k进行转移)
上式我们简化为f[i][j]=f[j-1][0]*a[0][i]+f[j-1][1]*a[1][i]+…+f[j-1][m-1]*a[m-1][i]
显然我们能够处理出a数组(看上面括号),而且想一想就可以得到初始的f就是a*单位矩阵,那么剩下的就是矩阵乘法快速幂了。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<queue> using namespace std; int n,m,k; char s[50]; int nxt[50]; void getnxt(){ for(int i=2,j=0;i<=m;i++){ while(j&&s[i]!=s[j+1])j=nxt[j]; if(s[i]==s[j+1])j++; nxt[i]=j; } return; } struct node{ int g[21][21]; }; void buildI(node &a){ for(int i=0;i<m;i++){ for(int j=0;j<m;j++){ a.g[i][j]=(i==j); } } } void multi(node x,node y,node &z){ memset(z.g,0,sizeof(z.g)); for(int i=0;i<m;i++){ for(int j=0;j<m;j++){ if(x.g[i][j]){ for(int l=0;l<m;l++){ z.g[i][l]+=x.g[i][j]%k*y.g[j][l]%k; z.g[i][l]%=k; } } } } return; } node a,b; void qpow(int k){ buildI(a); while(k){ if(k&1)multi(a,b,a); multi(b,b,b); k>>=1; } return; } int solve(){ int ans=0; qpow(n); for(int i=0;i<m;i++){ ans+=a.g[0][i]; ans%=k; } return ans; } int main(){ scanf("%d%d%d%s",&n,&m,&k,s+1); getnxt(); for(int i=0;i<m;i++){ for(char j='0';j<='9';j++){ int t=i; while(t&&s[t+1]!=j)t=nxt[t]; if(s[t+1]==j)t++; if(t!=m){ b.g[i][t]++;b.g[i][t]%=k; } } } printf("%d\n",solve()); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
- bzoj1009 [HNOI2008]GT考试
- [矩阵乘法+KMP] BZOJ1009: [HNOI2008]GT考试
- bzoj 1009: [HNOI2008]GT考试(dp+kmp+矩阵快速幂)
- [Bzoj1009][HNOI2008]GT考试(KMP)(矩乘优化DP)
- 【BZOJ 1009】 [HNOI2008]GT考试
- BZOJ1009: [HNOI2008]GT考试
- bzoj1009 [HNOI2008]GT考试
- [KMP DP 矩阵快速幂加速] BZOJ 1009 [HNOI2008]GT考试
- Bzoj1009: [HNOI2008]GT考试
- BZOJ 1009: [HNOI2008]GT考试【KMP上DP+矩阵快速幂
- BZOJ1009: [HNOI2008]GT考试
- bzoj1009: [HNOI2008]GT考试
- BZOJ1009: [HNOI2008]GT考试
- bzoj 1009: [HNOI2008]GT考试【kmp+dp+矩阵快速幂】
- bzoj1009 [HNOI2008]GT考试
- BZOJ 1009:[HNOI2008]GT考试
- BZOJ 1009 [HNOI2008]GT考试 ——矩阵乘法 KMP
- BZOJ1009 [HNOI2008]GT考试【kmp+矩阵加速DP】
- 【bzoj1009】【HNOI2008】【GT考试】
- 【BZOJ1009】GT考试(HNOI2008)-DP矩阵优化+KMP