码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ 8222 Substrings 后缀自动机

时间:2018-01-11 20:27:39      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:color   strlen   link   def   pre   spoj   cst   div   自动机   

 

You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string ‘ababa‘ F(3) will be 2 because there is a string ‘aba‘ that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.

Input

String S consists of at most 250000 lowercase latin letters.

Output

Output |S| lines. On the i-th line output F(i).

Example

Input:
ababa

Output:
3
2
2
1
1

没什么可说的
技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define maxn 500005
 8 using namespace std;
 9 char s[maxn];
10 int len;
11 struct data {
12     int son[maxn][26],link[maxn],step[maxn],last,cnt,size[maxn];
13     int v[maxn],pos[maxn],f[maxn];
14     data() {last=cnt=1;}
15     void extend(int c) {
16         int p=last,np=last=++cnt;step[np]=step[p]+1;size[np]=1;
17         while(p&&!son[p][c]) son[p][c]=np,p=link[p];
18         if(!p) link[np]=1;
19         else  {
20             int q=son[p][c];
21             if(step[q]==step[p]+1) link[np]=q;
22             else {
23                 int nq=++cnt;
24                 memcpy(son[nq],son[q],sizeof(son[q]));
25                 link[nq]=link[q];
26                 link[q]=link[np]=nq;
27                 step[nq]=step[p]+1;
28                 while(p&&son[p][c]==q) son[p][c]=nq,p=link[p];
29             }
30         }
31     }
32     void pre() {
33         for(int i=1;i<=cnt;i++) v[step[i]]++;
34         for(int i=1;i<=cnt;i++) v[i]+=v[i-1];
35         for(int i=cnt;i;i--) pos[v[step[i]]--]=i;
36         for(int i=cnt;i;i--) size[link[pos[i]]]+=size[pos[i]];
37         for(int i=1;i<=cnt;i++) f[step[i]]=max(f[step[i]],size[i]);
38         for(int i=len;i;i--) f[i]=max(f[i],f[i+1]);
39         for(int i=1;i<=len;i++) printf("%d\n",f[i]);
40     }
41 }sam;
42 int main() {
43     scanf("%s",s+1);
44     len=strlen(s+1);
45     for(int i=1;i<=len;i++) sam.extend(s[i]-a);
46     sam.pre();
47     return 0;
48 }
View Code

 

SPOJ 8222 Substrings 后缀自动机

标签:color   strlen   link   def   pre   spoj   cst   div   自动机   

原文地址:https://www.cnblogs.com/wls001/p/8270021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!