SPOJ

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

依次输出“出现次数最多的长度为x的字符串”的出现次数 (1<=x<=n)

后缀自动机

建出后缀自动机,统计每个节点标记的长度的出现次数即可。注意要倒序更新,把子节点(长串)的值累加到fa结点(长串的子串)的值上。

  ↑建好后缀自动机以后,要用原串在自动机上跑一便,每一个到达结点的初始次数r置为1。刚开始傻傻地把所有节点的r都初始化成1了,导致统计错误(理解不透彻)

顿悟:把后缀自动机的fa指针看成fail而不是father更直观 ←大概是我自己火星了)

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=500010;
 9 int read(){
10     int x=0,f=1;char ch=getchar();
11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 struct SAM{
16     int t[mxn][26];
17     int fa[mxn],l[mxn],r[mxn],rk[mxn];
18     int S,cnt,last;
19     int f[mxn],w[mxn];
20     void init(){S=cnt=last=1;return;}
21     void add(int c){
22         int p=last,np=++cnt;last=np;
23         l[np]=l[p]+1;
24         for(;p && !t[p][c];p=fa[p])t[p][c]=np;
25         if(!p){fa[np]=S;}
26         else{
27             int q=t[p][c];
28             if(l[q]==l[p]+1){fa[np]=q;}
29             else{
30                 int nq=++cnt;l[nq]=l[p]+1;
31                 memcpy(t[nq],t[q],sizeof t[q]);
32                 fa[nq]=fa[q];
33                 fa[np]=fa[q]=nq;
34                 for(;p && t[p][c]==q;p=fa[p])t[p][c]=nq;
35             }
36         }
37     }
38     void st(char *s,int n){
39 //        for(int i=1;i<=cnt;i++){r[i]=1;w[l[i]]++;}
40         int p=S;
41         for(int i=1;i<=n;i++){
42             p=t[p][s[i]-'a'];
43             r[p]++;
44         }
45         for(int i=1;i<=cnt;i++){w[l[i]]++;}
46         for(int i=1;i<=n;i++)w[i]+=w[i-1];
47         for(int i=1;i<=cnt;i++)rk[w[l[i]]--]=i;
48         return;
49     }
50     void solve(int n){
51         for(int i=cnt;i;i--){
52             int t=rk[i];
53             f[l[t]]=max(f[l[t]],r[t]);
54             r[fa[t]]+=r[t];
55         }
56         for(int i=n-1;i;i--)f[i]=max(f[i],f[i+1]);
57         return;
58     }
59 }sa;
60 char s[mxn];
61 int main(){
62     int i,j;
63     sa.init();
64     scanf("%s",s+1);
65     int len=strlen(s+1);
66     for(i=1;i<=len;i++){
67         sa.add(s[i]-'a');
68     }
69     sa.st(s,len);
70     sa.solve(len);
71     for(i=1;i<=len;i++)printf("%d
",sa.f[i]);
72     return 0;
73 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6420565.html