zoukankan      html  css  js  c++  java
  • 洛谷 SP1811 LCS

    传送门
    之前就用后缀数组做过,用字符串哈希做过,现在又用后缀自动机做一次。
    用后缀自动机求最长公共子串有两种做法,一是对 (s1) 建后缀自动机,然后把 (s2) 拿上去匹配。我用的是这个方法。
    二是对 (s1,s2) 建广义后缀自动机,然后直接算出每个节点的 (endpos_{1,2}),求 (endpos_1,endpos_2) 都为真的节点的 (len)。这个方法在之后的题中有体现。
    说一下在后缀自动机上匹配的操作的一些细节,都是在做的过程中想通的一点东西。
    (length) 为已匹配长度,从节点 (p=1) 开始匹配,如果 (ch[p][c]) 为真,那么 (p=ch[p][c],length++),这个操作很好理解,就是成功匹配。
    如果 (ch[p][c]) 为假,那么就将 (p)(fa[p]) 跳,实际上就是在已匹配的部分上扣掉前缀,直到 (ch[p][c]) 为真为止,然后重置 (length)

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    typedef long long LL;
    const int N=3e5+10;
    char s[N],t[N];
    int n,m,ans;
    struct SuffixAutoMachine{
    	int last=1,tot=1,ch[N*2][26],fa[N*2],len[N*2];
    	int newnode(int id){fa[++tot]=fa[id];len[tot]=len[id];memcpy(ch[tot],ch[id],sizeof(ch[tot]));return tot;}
    	void insert(int c){
    		int p=last,np=last=newnode(0);
    		len[np]=len[p]+1;
    		for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    		if(!p) {fa[np]=1;return;}
    		int q=ch[p][c];
    		if(len[q]==len[p]+1) {fa[np]=q;return;}
    		int nq=newnode(q);len[nq]=len[p]+1;
    		fa[q]=fa[np]=nq;
    		for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq; 
    	}
    	void init(){
    		for(int i=1;i<=n;i++) insert(s[i]-'a');
    		for(int i=1,leng=0,p=1;i<=m;i++){
    			if(ch[p][t[i]-'a']) leng++,p=ch[p][t[i]-'a'];
    			else {
    				for(;p&&!ch[p][t[i]-'a'];p=fa[p]);
    				if(p) leng=len[p]+1,p=ch[p][t[i]-'a'];
    				else p=1,leng=0;
    			}
    			ans=max(ans,leng);
    		}
    	}
    }sam;
    
    
    int main(){
    	scanf("%s%s",s+1,t+1);
    	n=strlen(s+1);
    	m=strlen(t+1);
    	sam.init();
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    linux cut的用法
    删除表的语句(drop truncate delete)
    mysql中的模糊查询
    linux之软连接 硬链接 link ln
    使用robot合并Robot Framework测试报告
    Python中的字典
    python logger 动态设置日志名
    K8S(Kubernetes)学习笔记
    [转]CURL常用命令
    python网站目录扫描器2.0版
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12670641.html
Copyright © 2011-2022 走看看