记录编号 182203 评测结果 AAAAAAAAAA
题目名称 [SPOJ 1676]文本生成器 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 0.126 s
提交时间 2015-08-27 14:18:40 内存使用 0.34 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<vector>
  7. #include<queue>
  8. #include<iomanip>
  9. using namespace std;
  10. int N,L;
  11. string str[20];
  12. int match[12]={0};//单词可以匹配的最大长度
  13. int s[12][8]={0};//单词i前j被匹配时的状态编号,s[0][0]代表空串,编号为1
  14. pair<int,int> stat[96];
  15. int mod=10007;
  16. int S;//总状态数
  17. class miku
  18. {
  19. public:
  20. int s[62][62];
  21. int m,n;//列和行
  22. miku()
  23. {
  24. m=n=0;
  25. memset(s,0,sizeof(s));
  26. }
  27. void print()
  28. {
  29. cout<<m<<" "<<n<<endl;
  30. for(int i=1;i<=n;i++)
  31. {
  32. for(int j=1;j<=m;j++)
  33. cout<<s[i][j]<<" ";
  34. cout<<endl;
  35. }
  36. }
  37. void make(int sn)
  38. {
  39. n=m=sn;
  40. for(int i=1;i<=n;i++)
  41. s[i][i]=1;
  42. }
  43. }G,D;
  44. miku operator * (miku a,miku b)
  45. {
  46. miku c;
  47. c.n=a.n;c.m=b.m;
  48. for(int i=1;i<=c.n;i++)
  49. for(int j=1;j<=c.m;j++)
  50. for(int k=1;k<=a.m;k++)
  51. {
  52. c.s[i][j]+=a.s[i][k]*b.s[k][j];
  53. c.s[i][j]%=mod;
  54. }
  55. return c;
  56. }
  57. inline miku quickpow(miku a,int b)
  58. {
  59. miku c;
  60. c.make(a.n);
  61. //c.print();
  62. while(b)
  63. {
  64. if(b&1) c=c*a;
  65. a=a*a;b>>=1;
  66. }
  67. return c;
  68. }
  69. int qmi(int y)
  70. {
  71. int re=1;
  72. int x=26;
  73. while(y>0)
  74. {
  75. if(y&1) re*=x;
  76. y>>=1;x*=x;re%=mod;x%=mod;
  77. }
  78. return re;
  79. }
  80. int find(string tem,int k)
  81. {
  82. int start=tem.size()-k;
  83. int i,j;
  84. for(i=1;i<=N;i++)
  85. {
  86. if(str[i].size()<k) continue;
  87. for(j=0;j<k;j++) if(str[i][j]!=tem[start+j]) goto NEXT;
  88. if(j==str[i].size()||j-1>match[i]) return -1;
  89. return i;
  90. NEXT:;
  91. }
  92. return 0;
  93. }
  94. int mamatch(string tem)
  95. {
  96. pair<int,int> ans;
  97. ans=make_pair(0,0);
  98. int j;
  99. for(int k=tem.size();k>=1;k--)
  100. {
  101. j=find(tem,k);
  102. if(j==-1) return 0;
  103. if(j)
  104. {
  105. ans=make_pair(j,k-1);
  106. break;
  107. }
  108. }
  109. return s[ans.first][ans.second];
  110. }
  111. void update()
  112. {
  113. int tot=1;//当前状态的编号
  114. s[0][0]=tot;stat[tot]=make_pair(0,-1);match[0]=-1;
  115. string tem;
  116. for(int i=1;i<=N;i++)
  117. {
  118. tem="\0";
  119. match[i]=str[i].size()-2;
  120. for(int j=0;j<str[i].size();j++)
  121. {
  122. tem+=str[i][j];
  123. //cout<<tem<<endl;
  124. int t;
  125. for(int k=1;k<=N;k++)
  126. {
  127. for(t=0;t<str[k].size();t++)
  128. {
  129. if(str[k][str[k].size()-1-t]!=tem[tem.size()-1-t]) break;
  130. }
  131. if(t==str[k].size())//完全匹配
  132. {
  133. match[i]=j-1;
  134. goto NEXT;
  135. //cout<<tem<<
  136. }
  137. }
  138. s[i][j]=++tot;
  139. stat[tot]=make_pair(i,j);
  140. //cout<<stat[tot].first<<" "<<stat[tot].second<<" "<<tot<<endl;
  141. }
  142. NEXT:;
  143. }
  144. S=tot;
  145. G.n=1;G.m=S;
  146. //cout<<S<<endl;
  147. for(int i=1;i<=S;i++) G.s[1][i]=1;
  148. D.m=D.n=S;
  149. for(int i=1;i<=S;i++)
  150. {
  151. tem="\0";
  152. for(int j=0;j<=stat[i].second;j++) tem+=str[stat[i].first][j];
  153. for(int j=0;j<26;j++)
  154. {
  155. int k=mamatch(tem+char(j+'A'));
  156. if(k) D.s[k][i]++;
  157. //cout<<k<<endl;
  158. }
  159. //cout<<tem<<endl;
  160. }
  161. }
  162. void work()
  163. {
  164. str[0]="\0";
  165. update();
  166. int ans=qmi(L);
  167. G=G*quickpow(D,L);
  168. ans-=G.s[1][1];
  169. ans=(ans+mod)%mod;
  170. printf("%d",ans);
  171. }
  172. int main()
  173. {
  174. freopen("textgen.in","r",stdin);
  175. freopen("textgen.out","w",stdout);
  176. scanf("%d%d",&N,&L);
  177. for(int i=1;i<=N;i++)
  178. cin>>str[i];
  179. work();
  180. return 0;
  181. }