题目描述
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|.
输入输出格式
输入格式:
String S consists of at most 250000 lowercase latin letters.
输出格式:
Output |S| lines. On the i-th line output F(i).
输入输出样例
输出样例#1:
3 2 2 1 1
对于每个节点x,i<=max{x}的f(i)都可以被size[x]更新,所以差分打个标记就可以了hhhh
今天刷后缀自动机真过瘾hhhh
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define maxn 1000005 using namespace std; int f[maxn],ch[maxn][26]; int l[maxn],siz[maxn],n; int tag[maxn],cnt=1,pre=1; int a[maxn],c[maxn]; char s[maxn]; inline void ins(int x){ int p=pre,np=++cnt; pre=np,l[np]=l[p]+1; siz[np]=1; for(;p&&!ch[p][x];p=f[p]) ch[p][x]=np; if(!p) f[np]=1; else{ int q=ch[p][x]; if(l[q]==l[p]+1) f[np]=q; else{ int nq=++cnt; l[nq]=l[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); f[nq]=f[q]; f[q]=f[np]=nq; for(;ch[p][x]==q;p=f[p]) ch[p][x]=nq; } } } inline void build(){ for(int i=0;i<n;i++) ins(s[i]-‘a‘); for(int i=1;i<=cnt;i++) c[l[i]]++; for(int i=n;i>=0;i--) c[i]+=c[i+1]; for(int i=1;i<=cnt;i++) a[c[l[i]]--]=i; } inline void solve(){ for(int i=1;i<=cnt;i++){ int now=a[i]; siz[f[now]]+=siz[now]; tag[l[now]]=max(tag[l[now]],siz[now]); } for(int i=n;i;i--) tag[i]=max(tag[i],tag[i+1]); } int main(){ scanf("%s",s); n=strlen(s); build(); solve(); for(int i=1;i<=n;i++) printf("%d\n",tag[i]); return 0; }