bzoj-2251 外星联络

来源:互联网 发布:中国象棋 知乎 编辑:程序博客网 时间:2024/04/28 09:56

题意:

给出一个字符串,求出现次数超过1的子串的出现个数;

字符串长度<=3000;


题解:

题目问的是子串的个数,那么首先我们要找到所有的子串;

而字符串的所有后缀的前缀可以不重不漏的表示所有子串;

那么如果将所有的后缀加入trie树,每个经过的结点——也就是这个后缀的前缀——计数+1;

然后题目要求按字典序输出,利用一下trie树性质搞好就完了;

指针版trie好慢啊。。。


代码:


#include<stdio.h>#include<string.h>#include<algorithm>#define N 3100using 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;}



0 0
原创粉丝点击