问题描述
BZOJ需要权限号
题解
字符串的性质:一个字符串(s)所有的字串,等于(s)所有后缀的前缀。
枚举这个字符串的每一个后缀,将其插入一个(mathrm{Trie})
在插入(mathrm{Trie})的过程中可以非常方便的维护这个后缀的每个前缀。
最后从(root)开始对整棵(mathrm{Trie})进行一次遍历即可。
(mathrm{Code})
#include<bits/stdc++.h>
using namespace std;
void read(int &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
char s[3007];
int ch[10000000][2],tot,root;//错误笔记:一开始数组开小十倍
int n,cnt[10000000];
void build(){
root=++tot;
}
int chk(char s){
return s-'0';
}
void insert(int pla){
int p=root;
for(register int i=pla;i<=n;i++){
int k=chk(s[i]);
if(!ch[p][k]) ch[p][k]=++tot;
p=ch[p][k];++cnt[p];
}
}
void dfs(int x){
if(cnt[x]>1&&x!=root) cout<<cnt[x]<<endl;
if(ch[x][0]) dfs(ch[x][0]);
if(ch[x][1]) dfs(ch[x][1]);
}
int main(){
ios::sync_with_stdio(0);
build();
cin>>n;cin>>(s+1);
for(register int i=n;i>=1;i--){
insert(i);
}
dfs(root);
return 0;
}