bzoj1009: [HNOI2008]GT考试

题解:

首先看到这道题n特别大,m很小,又有着很明显的状态转移,基本就可以看出这是一道矩阵优化dp题目了(终于不是在看完题解后再说了QAQ)

可以比较容易的看出状态转移,设f[i][j]表示长度为n的串匹配到了i,长度为m的串匹配到了j,预先处理m串的kmp,找到m串如何转移(我第一次写没有注意到需要处理kmp这回事,直接不符合的话转移到f[i][0]上,这样实际上是漏掉了情况);

然后构造一个使f[i]转移到f[i+1]的矩阵B,使f[i]*B=f[i+1];

然后用矩阵快速幂就行了;

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cstdlib>
 6 #include<ctime>
 7 #include<vector>
 8 #include<algorithm>
 9 #include<queue>
10 #include<map>
11 #include<vector>
12 #include<cmath>
13 using namespace std;
14 #define LL long long
15 #define FILE "1"
16 #define up(i,j,n) for(int i=j;i<=n;i++)
17 #define down(i,n,j) for(int i=n;i>=j;i--)
18 int n,m,k;
19 const int maxn=30;
20 char s[maxn];
21 struct M{
22     int v[maxn][maxn];
23     M(){memset(v,0,sizeof(v));}
24     friend M operator*(M a,M b){
25         M c;
26         for(int i=0;i<m;i++)
27             for(int j=0;j<m;j++)
28                 for(int h=0;h<m;h++)
29                     c.v[i][j]=(c.v[i][j]+a.v[i][h]*b.v[h][j])%k;
30         return c;
31     }
32     M operator^(int b){
33         M c;
34         for(int i=0;i<m;i++)c.v[i][i]=1;
35         while(b){
36             if(b%2)c=c*(*this);
37             b/=2;
38             *this=*this*(*this);
39         }
40         return c;
41     }
42 }a,b;
43 int next[maxn];
44 int main(){
45     //freopen("1.in","r",stdin);
46     scanf("%d%d%d",&n,&m,&k);
47     scanf("%s",s+1);
48     int j=0;next[1]=0;
49     for(int i=2;i<=m;i++){
50         while(j&&s[j+1]!=s[i])j=next[j];
51         if(s[j+1]==s[i])j++;
52         next[i]=j;
53     }
54     up(i,0,(m-1))up(j,0,9){
55         int t=i;
56         while(t&&s[t+1]-'0'!=j)t=next[t];
57         if(s[t+1]-'0'==j)t++;
58         b.v[i][t]=(b.v[i][t]+1)%k;
59     }
60     a.v[0][0]=1;
61     b=b^n;
62     a=a*b;
63     int sum=0;
64     for(int i=0;i<m;i++)sum=(sum+a.v[0][i])%k;
65     printf("%d\n",sum);
66     return 0;
67 }
View Code

 //这样的矩阵乘法时间复杂度很高,如果矩阵乘法的内容比较少还是自己写个比较好

posted @ 2016-09-25 22:04  CHADLZX  阅读(155)  评论(0编辑  收藏  举报