Qiuqiqiu  
不管道路多么崎岖坎坷,我永远不停下追逐梦想的脚步!

http://acm.hdu.edu.cn/showproblem.php?pid=2243

AC自动机+dp+矩阵

View Code
  1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4
5 /**MATRIX**************************************************************/
6 #define ET unsigned __int64
7 const int RC=30;
8 //const int md=9973;
9 struct matrix
10 {
11 int row,col;
12 ET mat[RC][RC];
13 static ET buf[RC][RC];
14 matrix()
15 {
16 row=col=0;
17 memset(mat,0,sizeof(mat));
18 }
19 matrix(int r,int c,ET a[][RC])
20 {
21 row=r; col=c;
22 memcpy(mat,a,sizeof(mat));
23 }
24 matrix unit()const
25 {
26 memset(buf,0,sizeof(buf));
27 for(int i=0;i<row;i++) buf[i][i]=1;
28 return matrix(row,col,buf);
29 }
30 matrix operator + (const matrix &B)const
31 {
32 memset(buf,0,sizeof(buf));
33 for (int i=0;i<row;i++)
34 for (int j=0;j<col;j++)
35 {
36 buf[i][j]=mat[i][j]+B.mat[i][j];
37 //buf[i][j]%=md;
38 }
39 return matrix(row,col,buf);
40 }
41 matrix operator * (const matrix &B)const
42 {
43 memset(buf,0,sizeof(buf));
44 for (int i=0;i<row;i++)
45 for (int j=0;j<B.col;j++)
46 for (int k=0;k<col;k++)
47 {
48 buf[i][j]+=mat[i][k]*B.mat[k][j];
49 //buf[i][j]%=md;
50 //buf[i][j]=(int)(((long long)mat[i][k]*B.mat[k][j]%md+buf[i][j])%md);
51 }
52 return matrix(row,B.col,buf);
53 }
54 void show()const
55 {
56 for (int i=0;i<row;i++)
57 {
58 for (int j=0;j<col;j++) printf("%d ",mat[i][j]);
59 printf("\n");
60 }
61 }
62 };
63 ET matrix::buf[RC][RC];
64 matrix pow(const matrix &a,int p)
65 {
66 matrix s=a.unit(),t=a;
67 int i;
68 for (i=p;i;i>>=1)
69 {
70 if (i&1) s=s*t;
71 t=t*t;
72 }
73 return s;
74 }
75 matrix powsum(const matrix &a,int p) //a^1+a^2+...+a^k
76 {
77 if (p==1) return a;
78 matrix t=powsum(a,p/2);
79 t=t*pow(a,p/2)+t;
80 if (p%2) t=t*a+a;
81 return t;
82 }
83 /*****************************************************************/
84
85 const int N=30,CH=26;
86 int chd[N][CH],key[N],fail[N],que[N],sz;
87 void insert(char *str)
88 {
89 int p=0;
90 for(int i=0;str[i];i++)
91 {
92 int c=str[i]-'a';
93 if(!chd[p][c]) chd[p][c]=++sz;
94 p=chd[p][c];
95 }
96 key[p]=1;
97 }
98 void AC()
99 {
100 int front=0,rear=0;
101 for(int i=0;i<CH;i++) if(chd[0][i])
102 {
103 int v=chd[0][i];
104 fail[v]=0;
105 que[rear++]=v;
106 }
107 while(front<rear)
108 {
109 int u=que[front++];
110 for(int i=0;i<CH;i++) if(chd[u][i])
111 {
112 int v=chd[u][i];
113 fail[v]=chd[fail[u]][i];
114 que[rear++]=v;
115 key[v]|=key[fail[v]];
116 }
117 else chd[u][i]=chd[fail[u]][i];
118 }
119 }
120 int main()
121 {
122 //freopen("in.txt","r",stdin);
123 int n,l;
124 while(~scanf("%d%d",&n,&l))
125 {
126 memset(chd,0,sizeof(chd));
127 memset(key,0,sizeof(key));
128 memset(fail,0,sizeof(fail));
129 sz=0;
130 for(int i=0;i<n;i++)
131 {
132 char w[10];
133 scanf("%s",w);
134 insert(w);
135 }
136 AC();
137 ET t[N][N];
138 memset(t,0,sizeof(t));
139 for(int i=0;i<=sz;i++)
140 if(key[i]) t[i][i]=CH;
141 else for(int j=0;j<CH;j++) t[chd[i][j]][i]++;
142 matrix a(sz+1,sz+1,t);
143 memset(t,0,sizeof(t)); t[0][0]=1;
144 matrix b(sz+1,1,t);
145 b=powsum(a,l)*b;
146 ET ans=0;
147 for(int i=0;i<=sz;i++)
148 if(key[i]) ans+=b.mat[i][0];
149 printf("%I64u\n",ans);
150 }
151 return 0;
152 }

 

posted on 2012-03-30 21:26  Qiuqiqiu  阅读(378)  评论(0编辑  收藏  举报