# [cf700E][后缀自动机]Cool Slogans

E. Cool Slogans
time limit per test4 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
Bomboslav set up a branding agency and now helps companies to create new logos and advertising slogans. In term of this problems, slogan of the company should be a non-empty substring of its name. For example, if the company name is “hornsandhoofs”, then substrings “sand” and “hor” could be its slogans, while strings “e” and “hornss” can not.

Sometimes the company performs rebranding and changes its slogan. Slogan A is considered to be cooler than slogan B if B appears in A as a substring at least twice (this occurrences are allowed to overlap). For example, slogan A =  “abacaba” is cooler than slogan B =  “ba”, slogan A =  “abcbcbe” is cooler than slogan B =  “bcb”, but slogan A =  “aaaaaa” is not cooler than slogan B =  “aba”.

You are given the company name w and your task is to help Bomboslav determine the length of the longest sequence of slogans s1, s2, …, sk, such that any slogan in the sequence is cooler than the previous one.

Input
The first line of the input contains a single integer n (1 ≤ n ≤ 200 000) — the length of the company name that asks Bomboslav to help. The second line contains the string w of length n, that consists of lowercase English letters.

Output
Print a single integer — the maximum possible length of the sequence of slogans of the company named w, such that any slogan in the sequence (except the first one) is cooler than the previous

Examples
inputCopy
3
abc
output
1
inputCopy
5
ddddd
output
5
inputCopy
11
abracadabra
output
3

## sol:

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

inline int read()
{
char c;
bool pd=0;
while((c=getchar())>'9'||c<'0')
if(c=='-') pd=1;
int res=c-'0';
while((c=getchar())>='0'&&c<='9')
res=(res<<3)+(res<<1)+c-'0';
return pd?-res:res;
}
int cnt=1,last=1;
const int N=410000;
int val[N],go[N][26],par[N];
inline void extend(int x)
{
int p=last;
int np=last=++cnt;
val[np]=val[p]+1;
while(!go[p][x]) go[p][x]=np,p=par[p];
if(!p) par[np]=1;
else
{
int q=go[p][x];
if(val[q]==val[p]+1) par[np]=q;
else
{
int nq=++cnt;
val[nq]=val[p]+1;
par[nq]=par[q];
for(int i=0;i<=25;++i) go[nq][i]=go[q][i];
par[q]=par[np]=nq;
while(go[p][x]==q) go[p][x]=nq,p=par[p];
}
}
}
int tot,fir[N],ed[N*2],nex[N*2];
inline void add(int x,int y)
{
nex[++tot]=fir[x];fir[x]=tot;ed[tot]=y;
nex[++tot]=fir[y];fir[y]=tot;ed[tot]=x;
}
int rt[N],key;
const int M=N*20;
int lc[M],rc[M],size[M];
inline int merge(int x,int y)
{
if(!x) return y;
if(!y) return x;
int now=++key;
size[now]=size[x]+size[y];
lc[now]=merge(lc[x],lc[y]);
rc[now]=merge(rc[x],rc[y]);
return now;
}
inline void modify(int &k,int l,int r,int x)
{
if(!k) k=++key;
size[k]++;
if(l==r) return;
int mid=l+r>>1;
if(mid>=x) modify(lc[k],l,mid,x);
else modify(rc[k],mid+1,r,x);
}
inline void query(int k,int l,int r,int L,int R,int &res)
{
if(!k) return;
if(L<=l&&r<=R)
{
res+=size[k];
return;
}
int mid=l+r>>1;
if(mid>=L) query(lc[k],l,mid,L,R,res);
if(mid< R) query(rc[k],mid+1,r,L,R,res);
}
int R[N],pos[N];
int father[N];
inline void dfs(int u,int fa)
{
int e,v;
father[u]=fa;
if(pos[u])
{
modify(rt[u],1,cnt,pos[u]);
R[u]=pos[u];
}
for(e=fir[u];v=ed[e],e;e=nex[e])
if(v!=fa)
{
dfs(v,u);
rt[u]=merge(rt[u],rt[v]);
R[u]=max(R[u],R[v]);
}
}
int ans[N];
int dep[N];
int fans;
int tfa[N];
inline void get_ans(int u,int fa)
{
int e,v;
dep[u]=dep[fa]+1;
for(e=fir[u];v=ed[e],e;e=nex[e])
if(v!=fa)
{
int res=0;
if(u!=1) query(rt[tfa[u]],1,cnt,R[v]-val[v]+val[father[tfa[u]]]+1,R[v],res);
if(res>=2||u==1) ans[v]=ans[u]+1,tfa[v]=v;
else ans[v]=ans[u],tfa[v]=tfa[u];
if(fans<ans[v]) fans=ans[v];
get_ans(v,u);
}
}
char sr[N];
int n;
int main()
{
//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);
n=read();
scanf("%s",sr+1);
//  n=strlen(sr+1);
int anser;
for(int i=1;i<=n;++i)
{
pos[cnt+1]=i;
if(i==n) anser=cnt+1;
extend(sr[i]-'a');
}
for(int i=1;i<=cnt;++i)
if(par[i]) add(par[i],i);
dfs(1,0);
//  dfs();
get_ans(1,0);
cout<<fans<<endl;
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120