LINK

广义 S A M SAM SAM离线

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6+10;
int n;
char a[maxn];
struct Tire
{
	int id,fa[maxn],col[maxn],zi[maxn][27];
	Tire() { id = 1; }
	inline void insert(char a[] )
	{
		int len = strlen( a+1 ), p = 1;
		for(int i=1;i<=len;i++)
		{
			int c = a[i]-'a';
			if( !zi[p][c] )	zi[p][c] = ++id,fa[id] = p, col[id] = c;
			p = zi[p][c];
		}
	}
}T;
struct extend_SAM
{
	int id,pos[maxn],fa[maxn],len[maxn],zi[maxn][27]; queue<int>q;
	extend_SAM(){ id = 1; }//初始化根节点为1
	int insert(int c,int las)
	{
		int p = las, np = ++id;
		len[np] = len[p]+1;
		for( ; p && zi[p][c]==0;p=fa[p] )	zi[p][c] = np;
		if( p==0 )	fa[np] = 1;
		else
		{
			int q = zi[p][c];
			if( len[q]==len[p]+1 )	fa[np] = q;
			else
			{
				int nq = ++id; 
				len[nq] = len[p]+1, fa[nq] = fa[q];
				memcpy( zi[nq],zi[q],sizeof zi[nq] );
				fa[q] = fa[np] = nq;
				for( ; p && zi[p][c]==q;p=fa[p] )	zi[p][c] = nq;
			}
		}
		return np;
	}
	void build()
	{
		for(int i=0;i<=25;i++)	if( T.zi[1][i] ) q.push( T.zi[1][i] );
		pos[1] = 1;
		while( !q.empty() )
		{
			int u = q.front(); q.pop();
			pos[u] = insert( T.col[u],pos[T.fa[u]] );
			for(int i=0;i<=25;i++)	if( T.zi[u][i] )	q.push( T.zi[u][i] );
		}
	}
	void solve()
	{
		long long ans = 0;
		for(int i=2;i<=id;i++)	ans += len[i]-len[fa[i]];
		printf("%lld",ans);
	}
}sam;
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)	scanf("%s",a+1),T.insert( a );
	sam.build(); sam.solve();
}

在线

int zi[maxn][12],fa[maxn],l[maxn],las=1,id=1;
void insert(int p,int c)
{
	if( zi[p][c] )
	{
		int q = zi[p][c];
		if( l[q]==l[p]+1 )	las = q;//完全吻合的节点 
		else
		{
			int nq = ++id; las = nq;
			memcpy( zi[nq],zi[q],sizeof zi[nq] );
			fa[nq] = fa[q], l[nq] = l[p]+1;
			fa[q] = nq;
			for( ; p&&zi[p][c]==q;p=fa[p] )	zi[p][c] = nq;
		}
	}
	else
	{
		int np = ++id; las = np;
		l[np] = l[p]+1;
		for( ; p&&zi[p][c]==0 ; p = fa[p] )	zi[p][c] = np;
		if( !p )	fa[np] = 1;
		else
		{
			int q = zi[p][c];
			if( l[q]==l[p]+1 )	fa[np] = q;
			else
			{
				int nq = ++id;
				memcpy( zi[nq],zi[q],sizeof zi[nq] );
				fa[nq] = fa[q], l[nq] = l[p]+1;
				fa[np] = fa[q] = nq;
				for( ; p&&zi[p][c]==q;p=fa[p] )	zi[p][c] = nq;	
			} 
		}
	}
}