SAM求SA
暂时不打算深入研究\(SA\)。
所以只能靠\(SAM\)了。
\(loj111 Code:\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000005
using namespace std;
char s[N];
char obuf[1 << 23],*O=obuf;
int n,cnt=1,lst=1,tr[N << 1][70],pre[N << 1],len[N << 1],R[N << 1],vis[N << 1];
int c[75],a[N << 1],ans[N];
int trans(char c)
{
if ('0'<=c && c<='9')
return c-'0';
if ('A'<=c && c<='Z')
return c-'A'+10;
if ('a'<=c && c<='z')
return c-'a'+36;
}
void ins(int c,int I)
{
int np=++cnt,p=lst;
len[np]=len[p]+1,lst=np,R[np]=I,vis[np]=I;
for (;p && !tr[p][c];p=pre[p])
tr[p][c]=np;
if (!p)
pre[np]=1; else
{
int q=tr[p][c];
if (len[p]+1==len[q])
pre[np]=q; else
{
int g=++cnt;
memcpy(tr[g],tr[q],sizeof(tr[q]));
len[g]=len[p]+1,pre[g]=pre[q],R[g]=R[q];
for(;p && tr[p][c]==q;p=pre[p])
tr[p][c]=g;
pre[np]=pre[q]=g;
}
}
}
struct edge
{
int nxt,v;
edge (int Nxt=0,int V=0)
{
nxt=Nxt,v=V;
}
}e[N << 1];
int tot,fr[N << 1];
void add(int x,int y)
{
++tot;
e[tot]=edge(fr[x],y),fr[x]=tot;
}
void dfs(int u)
{
if (vis[u])
ans[++ans[0]]=n-vis[u]+1;
for (int i=fr[u];i;i=e[i].nxt)
{
int v=e[i].v;
dfs(v);
}
}
void write(int x)
{
if (x>9)
write(x/10);
*O++=x%10+'0';
}
int main()
{
scanf("%s",s+1),n=strlen(s+1);
reverse(s+1,s+n+1);
for (int i=1;i<=n;++i)
ins(trans(s[i]),i);
for (int i=2;i<=cnt;++i)
++c[trans(s[R[i]-len[pre[i]]])];
for (int i=1;i<62;++i)
c[i]+=c[i-1];
for (int i=2;i<=cnt;++i)
a[c[trans(s[R[i]-len[pre[i]]])]--]=i;
for (int i=cnt;i;--i)
add(pre[a[i]],a[i]);
dfs(1);
for (int i=1;i<=n;++i)
write(ans[i]),*O++=' ';
*O++='\n';
fwrite(obuf,O-obuf,1,stdout);
return 0;
}