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 }