码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2946 Poi2000 公共串 后缀自动机

时间:2015-03-09 22:36:25      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj2946   后缀自动机   

题目大意:求n个串的最长公共子串

太久没写SAM了真是……

将第一个串建成后缀自动机,用其它的串进去匹配

每个节点记录每个串在上面匹配的最大长度

那么这个节点对答案的贡献就是所有最大长度的最小值

对所有贡献取最大就行了= = 这最大最小看着真是别扭

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 10100
using namespace std;
int n,ans;
char s[M];
namespace Suffix_Automaton{
	struct SAM{
		SAM *parent,*son[26];
		int max_len,min_len[6];
		bool v;
		SAM(int _=0):parent(0x0),max_len(_),v(false)
		{
			memset(son,0,sizeof son);
			memset(min_len,0,sizeof min_len);
		}
	}*root=new SAM,*last=root;
	void Extend(int x)
	{
		SAM *p=last;
		SAM *np=new SAM(p->max_len+1);
		while(p&&!p->son[x])
			p->son[x]=np,p=p->parent;
		if(!p) np->parent=root;
		else
		{
			SAM *q=p->son[x];
			if(p->max_len+1==q->max_len)
				np->parent=q;
			else
			{
				SAM *nq=new SAM(p->max_len+1);
				nq->parent=q->parent;
				memcpy(nq->son,q->son,sizeof nq->son);
				q->parent=nq;np->parent=nq;
				for(;p&&p->son[x]==q;p=p->parent)
					p->son[x]=nq;
				nq->min_len[1]=nq->max_len;
			}
		}
		last=np;
		np->min_len[1]=np->max_len;
	}
	void DFS(SAM *p)
	{
		int i,temp=0x3f3f3f3f;
		for(i=1;i<=n;i++)
			temp=min(temp,p->min_len[i]);
		ans=max(ans,temp);
		p->v=true;
		for(i=0;i<26;i++)
			if( p->son[i] && !p->son[i]->v )
				DFS(p->son[i]);
	}
}
int main()
{
	using namespace Suffix_Automaton;
	int i,j;
	cin>>n;
	scanf("%s",s+1);
	for(i=1;s[i];i++)
		Extend(s[i]-'a');
	for(i=2;i<=n;i++)
	{
		scanf("%s",s+1);
		SAM *p=root;int len=0;
		for(j=1;s[j];j++)
		{
			while( p!=root && !p->son[s[j]-'a'] )
				p=p->parent,len=p->max_len;
			if( p->son[s[j]-'a'] )
				p=p->son[s[j]-'a'],len++;
			for(SAM* temp=p;temp;temp=temp->parent)
				temp->min_len[i]=max(temp->min_len[i],min(len,temp->max_len) );
		}
	}
	DFS(root);
	cout<<ans<<endl;
}


BZOJ 2946 Poi2000 公共串 后缀自动机

标签:bzoj   bzoj2946   后缀自动机   

原文地址:http://blog.csdn.net/popoqqq/article/details/44159991

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!