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 }