Crazy Search

poj1200:http://poj.org/problem?id=1200

题意:给你一个有m种字符串,求长度为n的连续子串由多少种。

题解:网上的代码都是hash,但是本人觉得hash有问题,就是n,m稍微大点,hash的值都会爆出int,无法开数组来记录该串是否被记录。可能数据弱,结果hash竟然A了

。正确的解法是用set来存,把所有的hash值放进set,set有去重效果,最后求一下set的大小。但是这样结果是T了。不知道这题怎么解。一下是第一种代码。于是换别的,trie树来搞。

 1 #include<cstring>
 2 #include<vector>
 3 #include<cstdio>
 4 using namespace std;
 5 const int maxnode = 4000 * 1000 + 10;
 6 const int sigma_size = 26;
 7 int ans;
 8 struct Trie {
 9   int head[maxnode]; // head[i]为第i个结点的左儿子编号
10   int next[maxnode]; // next[i]为第i个结点的右兄弟编号
11   char ch[maxnode];  // ch[i]为第i个结点上的字符
12   int sz; // 结点总数
13   void clear() {
14     sz = 1;
15     head[0] = next[0] = 0;
16      }
17   void insert(const char *s,int form ,int to) {
18     int u = 0, v;
19     int temp=sz;
20     for(int i = form; i <to; i++) {
21       bool found = false;
22       for(v = head[u]; v != 0; v = next[v])
23         if(ch[v] == s[i]) { // 找到了
24           found = true;
25           break;
26         }
27       if(!found) {
28         v = sz++; // 新建结点
29         ch[v] = s[i];
30         next[v] = head[u];
31         head[u] = v; // 插入到链表的首部
32         head[v] = 0;
33       }
34       u = v;
35     }
36     if(temp==sz)ans++;
37 }
38 }trie;
39 int n,m;
40 char word[10000002];
41 int main() {
42   while(~scanf("%d %d", &n,&m)) {
43        trie.clear();
44       scanf("%s", word);
45       m=strlen(word);
46       ans=0;
47       for(int i=0;i+n<=m;i++){
48          trie.insert(word,i,i+n);
49       }
50      printf("%d
",m+1-n-ans);
51   }
52   return 0;
53 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3903468.html