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;
}
posted @ 2020-12-20 19:51  GK0328  阅读(117)  评论(0编辑  收藏  举报