Censored!
Time Limit: 5000MS   Memory Limit: 10000K
Total Submissions: 6956   Accepted: 1887

Description

The alphabet of Freeland consists of exactly N letters. Each sentence of Freeland language (also known as Freish) consists of exactly M letters without word breaks. So, there exist exactly N^M different Freish sentences.

But after recent election of Mr. Grass Jr. as Freeland president some words offending him were declared unprintable and all sentences containing at least one of them were forbidden. The sentence S contains a word W if W is a substring of S i.e. exists such k >= 1 that S[k] = W[1], S[k+1] = W[2], ...,S[k+len(W)-1] = W[len(W)], where k+len(W)-1 <= M and len(W) denotes length of W. Everyone who uses a forbidden sentence is to be put to jail for 10 years.

Find out how many different sentences can be used now by freelanders without risk to be put to jail for using it.

Input

The first line of the input file contains three integer numbers: N -- the number of letters in Freish alphabet, M -- the length of all Freish sentences and P -- the number of forbidden words (1 <= N <= 50, 1 <= M <= 50, 0 <= P <= 10).

The second line contains exactly N different characters -- the letters of the Freish alphabet (all with ASCII code greater than 32).

The following P lines contain forbidden words, each not longer than min(M, 10) characters, all containing only letters of Freish alphabet.

Output

Output the only integer number -- the number of different sentences freelanders can safely use.

Sample Input

  1. 2 3 1
  2. ab
  3. bb

Sample Output

  1. 5

Source

Northeastern Europe 2001, Northern Subregion
 
 
很好的题目。。。
 
注意字符貌似会有超过128的,用map转化下就好了。
 
然后就是用AC自动机实现状态表。
然后高精度 进行简单的DP;
 
  1. //============================================================================
  2. // Name : POJ.cpp
  3. // Author :
  4. // Version :
  5. // Copyright : Your copyright notice
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8.  
  9. #include <iostream>
  10. #include <string.h>
  11. #include <algorithm>
  12. #include <stdio.h>
  13. #include <queue>
  14. #include <map>
  15. using namespace std;
  16. map<char,int>mp;
  17. int N,M,P;
  18. struct Matrix
  19. {
  20. int mat[][];
  21. int n;
  22. Matrix(){}
  23. Matrix(int _n)
  24. {
  25. n=_n;
  26. for(int i = ;i < n;i++)
  27. for(int j = ;j < n;j++)
  28. mat[i][j] = ;
  29. }
  30. };
  31. struct Trie
  32. {
  33. int next[][],fail[];
  34. bool end[];
  35. int L,root;
  36. int newnode()
  37. {
  38. for(int i = ;i < ;i++)
  39. next[L][i] = -;
  40. end[L++] = false;
  41. return L-;
  42. }
  43. void init()
  44. {
  45. L = ;
  46. root = newnode();
  47. }
  48. void insert(char buf[])
  49. {
  50. int len = strlen(buf);
  51. int now = root;
  52. for(int i = ;i < len;i++)
  53. {
  54. if(next[now][mp[buf[i]]] == -)
  55. next[now][mp[buf[i]]] = newnode();
  56. now = next[now][mp[buf[i]]];
  57. }
  58. end[now] = true;
  59. }
  60. void build()
  61. {
  62. queue<int>Q;
  63. fail[root] = root;
  64. for(int i = ;i < ;i++)
  65. if(next[root][i] == -)
  66. next[root][i] = root;
  67. else
  68. {
  69. fail[next[root][i]] = root;
  70. Q.push(next[root][i]);
  71. }
  72. while(!Q.empty())
  73. {
  74. int now = Q.front();
  75. Q.pop();
  76. if(end[fail[now]]==true)end[now]=true;
  77. for(int i = ;i < ;i++)
  78. if(next[now][i] == -)
  79. next[now][i] = next[fail[now]][i];
  80. else
  81. {
  82. fail[next[now][i]] = next[fail[now]][i];
  83. Q.push(next[now][i]);
  84. }
  85. }
  86. }
  87. Matrix getMatrix()
  88. {
  89. Matrix res = Matrix(L);
  90. for(int i = ;i < L;i++)
  91. for(int j = ;j < N;j++)
  92. if(end[next[i][j]]==false)
  93. res.mat[i][next[i][j]]++;
  94. return res;
  95. }
  96. void debug()
  97. {
  98. for(int i = ;i < L;i++)
  99. {
  100. printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
  101. for(int j = ;j < ;j++)
  102. printf("%2d",next[i][j]);
  103. printf("]\n");
  104. }
  105. }
  106.  
  107. };
  108.  
  109. /*
  110. * 高精度,支持乘法和加法
  111. */
  112. struct BigInt
  113. {
  114. const static int mod = ;
  115. const static int DLEN = ;
  116. int a[],len;
  117. BigInt()
  118. {
  119. memset(a,,sizeof(a));
  120. len = ;
  121. }
  122. BigInt(int v)
  123. {
  124. memset(a,,sizeof(a));
  125. len = ;
  126. do
  127. {
  128. a[len++] = v%mod;
  129. v /= mod;
  130. }while(v);
  131. }
  132. BigInt(const char s[])
  133. {
  134. memset(a,,sizeof(a));
  135. int L = strlen(s);
  136. len = L/DLEN;
  137. if(L%DLEN)len++;
  138. int index = ;
  139. for(int i = L-;i >= ;i -= DLEN)
  140. {
  141. int t = ;
  142. int k = i - DLEN + ;
  143. if(k < )k = ;
  144. for(int j = k;j <= i;j++)
  145. t = t* + s[j] - '';
  146. a[index++] = t;
  147. }
  148. }
  149. BigInt operator +(const BigInt &b)const
  150. {
  151. BigInt res;
  152. res.len = max(len,b.len);
  153. for(int i = ;i <= res.len;i++)
  154. res.a[i] = ;
  155. for(int i = ;i < res.len;i++)
  156. {
  157. res.a[i] += ((i < len)?a[i]:)+((i < b.len)?b.a[i]:);
  158. res.a[i+] += res.a[i]/mod;
  159. res.a[i] %= mod;
  160. }
  161. if(res.a[res.len] > )res.len++;
  162. return res;
  163. }
  164. BigInt operator *(const BigInt &b)const
  165. {
  166. BigInt res;
  167. for(int i = ; i < len;i++)
  168. {
  169. int up = ;
  170. for(int j = ;j < b.len;j++)
  171. {
  172. int temp = a[i]*b.a[j] + res.a[i+j] + up;
  173. res.a[i+j] = temp%mod;
  174. up = temp/mod;
  175. }
  176. if(up != )
  177. res.a[i + b.len] = up;
  178. }
  179. res.len = len + b.len;
  180. while(res.a[res.len - ] == &&res.len > )res.len--;
  181. return res;
  182. }
  183. void output()
  184. {
  185. printf("%d",a[len-]);
  186. for(int i = len-;i >= ;i--)
  187. printf("%04d",a[i]);
  188. printf("\n");
  189. }
  190. };
  191. char buf[];
  192. BigInt dp[][];
  193. Trie ac;
  194. int main()
  195. {
  196. // freopen("in.txt","r",stdin);
  197. // freopen("out.txt","w",stdout);
  198.  
  199. while(scanf("%d%d%d",&N,&M,&P)==)
  200. {
  201. gets(buf);
  202. gets(buf);
  203. mp.clear();
  204. int len = strlen(buf);
  205. for(int i = ;i < len;i++)
  206. mp[buf[i]]=i;
  207. ac.init();
  208. for(int i = ;i < P;i++)
  209. {
  210. gets(buf);
  211. ac.insert(buf);
  212. }
  213. ac.build();
  214. // ac.debug();
  215. Matrix a= ac.getMatrix();
  216.  
  217. // for(int i = 0;i <a.n;i++)
  218. // {
  219. // for(int j=0;j<a.n;j++)printf("%d ",a.mat[i][j]);
  220. // cout<<endl;
  221. // }
  222.  
  223. int now = ;
  224. dp[now][] = ;
  225. for(int i = ;i < a.n;i++)
  226. dp[now][i] = ;
  227. for(int i = ;i < M;i++)
  228. {
  229. now^=;
  230. for(int j = ;j < a.n;j++)
  231. dp[now][j] = ;
  232. for(int j = ;j < a.n;j++)
  233. for(int k = ;k < a.n;k++)
  234. if(a.mat[j][k] > )
  235. dp[now][k] = dp[now][k]+dp[now^][j]*a.mat[j][k];
  236. // for(int j = 0;j < a.n;j++)
  237. // dp[now][j].output();
  238. }
  239. BigInt ans = ;
  240. for(int i = ;i < a.n;i++)
  241. ans = ans + dp[now][i];
  242. ans.output();
  243. }
  244. return ;
  245. }
 
 
 
 
 
 

POJ 1625 Censored!(AC自动机+DP+高精度)的更多相关文章

  1. Match:Censored!(AC自动机+DP+高精度)(POJ 1625)

     Censored! 题目大意:给定一些字符,将这些字符组成一个固定长度的字符串,但是字符串不能包含一些禁词,问你有多少种组合方式. 这是一道好题,既然出现了“一些”禁词,那么这题肯定和AC自动机有点 ...

  2. POJ 1625 Censored! [AC自动机 高精度]

    Censored! Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 9793   Accepted: 2686 Descrip ...

  3. POJ 1625 Censored ( Trie图 && DP && 高精度 )

    题意 : 给出 n 个单词组成的字符集 以及 p 个非法串,问你用字符集里面的单词构造长度为 m 的单词的方案数有多少种? 分析 :先构造出 Trie 图方便进行状态转移,这与在 POJ 2278 中 ...

  4. [POJ1625]Censored!(AC自动机+DP+高精度)

    Censored! Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10824   Accepted: 2966 Descri ...

  5. poj 1625 (AC自动机好模版,大数好模版)

    题目 给n个字母,构成长度为m的串,总共有n^m种.给p个字符串,问n^m种字符串中不包含(不是子串)这p个字符串的个数. 将p个不能包含的字符串建立AC自动机,每个结点用val值来标记以当前节点为后 ...

  6. POJ1625 Censored! —— AC自动机 + DP + 大数

    题目链接:https://vjudge.net/problem/POJ-1625 Censored! Time Limit: 5000MS   Memory Limit: 10000K Total S ...

  7. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  8. 对AC自动机+DP题的一些汇总与一丝总结 (2)

    POJ 2778 DNA Sequence (1)题意 : 给出m个病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 关键字眼:不包含,个数,长度 DP[i][j] : 表示长 ...

  9. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

随机推荐

  1. 【Unity3D】Invoke,InvokeRepeating ,Coroutine 延迟调用,周期性调用

    Invoke和InvokeRepeating方法,可以实现延迟调用,和周期调用 第一个是执行一次,第二个是重复执行 void Invoke(string methodName, float time) ...

  2. 4.js模式-发布-订阅模式

    1. 发布-订阅模式 var observe = (function(){ var events = {}, listen, trigger, remmove; listen = function(k ...

  3. HTML~From

    表单用于向服务器传输数据. http://www.w3school.com.cn/tags/tag_form.asp 文本域(Text fields) 本例演示如何在HTML页面创建文本域.用户可以在 ...

  4. Effective C++ -----条款20:宁以pass-by-reference-to-const替换pass-by-value Prefer pass-by-reference-to-const to pass-by-value

    尽量以pass-by-reference-to-const替换pass-by-value.前者通常比较高校,并可避免切割问题(slicing problem). 以上规则并不适用于内置类型,以及STL ...

  5. 表现层的设计(一)——常用的模式、Json与DTO

    上几篇博文介绍了 业务逻辑层和数据访问层,我认为写博文的作用主要是向业界的读者交流一种思想,点到为止,至于学习架构设计,通过几篇博文是讲不清楚的,还需要[基础]扎实的情况下,[反复]研究[权威]的书籍 ...

  6. 【processing】小代码3

    鼠标响应: mouseX, mouseY 鼠标的坐标 ---------------------------------------------- void setup() { size(,); sm ...

  7. 【xml】利用OpenCV解析

    看到一篇讲的很清楚的博客:http://blog.csdn.net/jarvischu/article/details/8481510

  8. Myeclipse编写struts程序

    说到struts则必须要谈到MVC模式(Model2) 什么是MVC模式.随着应用系统的逐渐增大,系统的业务逻辑复杂度以几何级数方式增加,在这样的情况下,如果还是把所有的处理逻辑都放在JSP页面中,那 ...

  9. javascript测试

    s阿道夫. 撒旦法 sd sad sd 的萨法a dsa发 fds sdfad 电风扇爱的方式爱的方式啊

  10. CountdownLatchTest

    import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java ...