SPOJ distinct subtrings

题目链接:戳我

后缀自动机模板?
求不同的子串数量。
直接\(\sum t[i].len-t[t[i].ff].len\)即可

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 1010
char a[MAXN];
long long ans;
int tot=1,last=1,T;
struct Node{int son[26],ff,len;}t[MAXN<<1];
inline void extend(int c)
{
	int p=last,np=++tot;last=np;
	t[np].len=t[p].len+1;
	while(p&&!t[p].son[c]) t[p].son[c]=np,p=t[p].ff;
	if(!p)t[np].ff=1;
	else
	{
		int q=t[p].son[c];
		if(t[p].len+1==t[q].len) t[np].ff=q;
		else
		{
			int nq=++tot;
			t[nq]=t[q];
			t[nq].len=t[p].len+1;
			t[q].ff=t[np].ff=nq;
			while(p&&t[p].son[c]==q) t[p].son[c]=nq,p=t[p].ff;
		}
	 }	
}
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("ce.in","r",stdin);
	#endif
	scanf("%d",&T);
	while(T--)
	{
		scanf("%s",a+1);
		last=tot=1;
		int lenth=strlen(a+1),ans=0;
		memset(t,0,sizeof(t));
		for(int i=1;i<=lenth;i++) extend(a[i]-'A');
		for(int i=1;i<=tot;i++) ans+=t[i].len-t[t[i].ff].len;
		printf("%lld\n",ans);
	}
	return 0;
}

posted @ 2019-02-15 15:16  风浔凌  阅读(120)  评论(0编辑  收藏  举报