后缀自动机SAM(lzz)

#include<cstdio>
#include<cstring>
#define ll long long
const int N=1000010;
int head[N<<1];
int next[N<<1];
int goal[N<<1];

ll ans=0;
ll max(ll a,ll b)
{
	if(a>b)return a;
	return b;
}
void add(int a,int b,int e)
{
	next[e]=head[a];
	head[a]=e;
	goal[e]=b;
	return;
}
struct samnode{
	int son[26];
	int fa,len;
	int count;
};
struct SAM{
	samnode t[N<<1];
	int last,tot;
	void init()
	{
		last=tot=1;
		int k,i;
		for(k=0;k<N<<1;k++)
		{
			for(i=0;i<26;i++)t[k].son[i]=0;
			t[k].fa=t[k].len=0;
		}
		t[1].count=0;
		return;
	}
	void insert(int x)
	{
		int k,i,j;
		int p,np,q,nq;
		p=last; np=++tot; last=np;
		t[np].len=t[p].len+1;
		t[np].count=1;
		while(!t[p].son[x] && p)
		{
			t[p].son[x]=np;
			p=t[p].fa;
		}
		if(!p)t[np].fa=1;
		else
		{
			q=t[p].son[x];
			if(t[q].len==t[p].len+1)t[np].fa=q;
			else
			{
				nq=++tot;
				t[nq]=t[q]; t[nq].len=t[p].len+1;
				t[np].fa=t[q].fa=nq;
				t[nq].count=0;
				while(p && t[p].son[x]==q)
				{
					t[p].son[x]=nq;
					p=t[p].fa;
				}
			}
		}
	}
}sam;
int dfs(int x)
{
	int k,i=sam.t[x].count;
	for(k=head[x];k!=-1;k=next[k])
	{
		i+=dfs(goal[k]);
	}
	if(i!=1)ans=max(ans,1ll*sam.t[x].len*i);
	return i;
}
int main()
{
	int k,i,j;
	char ch[N];
	memset(head,-1,sizeof(head));
	sam.init();
	scanf("%s",&ch);
	for(k=0;ch[k];k++)sam.insert(ch[k]-'a');
	for(k=1;k<=sam.tot;k++)add(sam.t[k].fa,k,k);
	dfs(1);
	printf("%d\n",ans);
	return 0;
}
posted @ 2022-03-15 22:32  wild_chicken  阅读(17)  评论(0)    收藏  举报