zoukankan      html  css  js  c++  java
  • bzoj 2946: [Poi2000]公共串【SAM】

    对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案
    注意在一个点更新后它的祖先也会被更新,需要最后按拓扑序向上更新一边
    其实二分+hash就行

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=10005;
    int n,m,ch[N][26],fa[N],tot=1,cur=1,la,dis[N],sa[N],wsu[N],l[N],mn[N],ans;
    char s[N];
    void ins(int c,int id)
    {
    	la=cur,dis[cur=++tot]=id;
    	int p=la;
    	for(;p&&!ch[p][c];p=fa[p])
    		ch[p][c]=cur;
    	if(!p)
    		fa[cur]=1;
    	else
    	{
    		int q=ch[p][c];
    		if(dis[q]==dis[p]+1)
    			fa[cur]=q;
    		else
    		{
    			int nq=++tot;
    			dis[nq]=dis[p]+1;
    			memcpy(ch[nq],ch[q],sizeof(ch[q]));
    			fa[nq]=fa[q];
    			fa[q]=fa[cur]=nq;
    			for(;ch[p][c]==q;p=fa[p])
    				ch[p][c]=nq;
    		}
    	}
    }
    void wk()
    {
    	scanf("%s",s+1);
    	memset(l,0,sizeof(l));
    	int n=strlen(s+1),nw=1;
    	for(int i=1,len=1;i<=n;i++)
    	{
    		while(nw&&!ch[nw][s[i]-'a'])
    			nw=fa[nw];
    		if(!nw)
    			nw=1,len=0;
    		else
    			len=min(len,dis[nw])+1,nw=ch[nw][s[i]-'a'];//cerr<<len<<endl;
    		l[nw]=max(l[nw],len);
    	}
    	for(int i=tot;i>=2;i--)
    		l[fa[sa[i]]]=max(l[fa[sa[i]]],min(dis[fa[sa[i]]],l[sa[i]]));
    	// for(int i=2;i<=tot;i++)
    		// cerr<<l[i]<<" ";cerr<<endl;
    	for(int i=2;i<=tot;i++)
    		mn[i]=min(mn[i],l[i]);//,cerr<<mn[i]<<" ";cerr<<endl;
    }
    int main()
    {
    	scanf("%d%s",&n,s+1);
    	m=strlen(s+1);
    	if(n==1)
    	{
    		printf("%d
    ",m);
    		return 0;
    	}
    	for(int i=1;i<=m;i++)
    		ins(s[i]-'a',i);
    	for(int i=2;i<=tot;i++)
    		wsu[dis[i]]++;
    	for(int i=1;i<=m;i++)
    		wsu[i]+=wsu[i-1];
    	for(int i=m;i>=1;i--)
    		sa[wsu[dis[i]]--]=i;
    	for(int i=2;i<=tot;i++)
    		mn[i]=dis[i];//,cerr<<mn[i]<<" ";cerr<<endl;
    	for(int i=2;i<=n;i++)
    		wk();
    	for(int i=2;i<=tot;i++)
    		ans=max(ans,mn[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    LeetCode522. 最长特殊序列 II
    docker activiti部署到Linux环境,流程图乱码
    linux docker 命令
    linux 安装docker
    JSON,JSONOBJECT,JSONARRAY 互转
    Python和java 的区别笔记(未完成)
    程序员常读书单整理,附下载地址
    javaweb同一个项目打包两次放在同一个tomcat下
    SSM项目集成Redis
    Chrome浏览器崩溃
  • 原文地址:https://www.cnblogs.com/lokiii/p/10712757.html
Copyright © 2011-2022 走看看