bzoj-2251 外星联络
2017-07-10 16:13 tlnshuju 阅读(143) 评论(0) 编辑 收藏 举报题意:
给出一个字符串,求出现次数超过1的子串的出现个数。
字符串长度<=3000;
题解:
题目问的是子串的个数。那么首先我们要找到全部的子串。
而字符串的全部后缀的前缀能够不重不漏的表示全部子串;
那么假设将全部的后缀增加trie树。每一个经过的结点——也就是这个后缀的前缀——计数+1。
然后题目要求按字典序输出。利用一下trie树性质搞好就完了。
指针版trie好慢啊。
。。
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #define N 3100 using namespace std; struct trie { int cnt; trie *next[2]; trie() { next[0]=next[1]=NULL; cnt=0; } }*root=new trie(); char str[N]; void insert(char *s) { bool index; trie *p=root; while(*s!='\0') { index=*s-'0'; if(p->next[index]==NULL) p->next[index]=new trie(); p=p->next[index]; p->cnt++; s++; } } void dfs(trie *p) { if(p->cnt>1) printf("%d\n",p->cnt); if(p->next[0]!=NULL) dfs(p->next[0]); if(p->next[1]!=NULL) dfs(p->next[1]); } int main() { int n,m,i,j,k; scanf("%d%s",&n,str+1); for(i=1;i<=n;i++) insert(str+i); dfs(root); return 0; }