• CF427D Match & Catch【广义SAM】


    传送门
    没啥好说的,建好广义 SAM 后统计 (endpos),然后选 (endpos1,endpos2) 都为 1 的点的长度最小值就是答案。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=5e4+10;
    const int inf=0x3f3f3f3f;
    int n;
    char s[N];
    struct SuffixAutoMachine{
    	int tot=1,fa[N*2],len[N*2],ch[N*2][26],epos[N*2][2],a[N*2],c[N];
    	int newnode(int x){fa[++tot]=fa[x];len[tot]=len[x];memcpy(ch[tot],ch[x],sizeof(ch[tot]));return tot;}
    	int extend(int p,int c){
    		int q=ch[p][c],nq=newnode(q);
    		len[nq]=len[p]+1;fa[q]=nq;
    		for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    		return nq;
    	}
    	int append(int p,int c){
    		if(ch[p][c]) if(len[ch[p][c]]==len[p]+1) return ch[p][c];else return extend(p,c);
    		int np=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 np;}
    		if(len[ch[p][c]]==len[p]+1) fa[np]=ch[p][c];
    		else fa[np]=extend(p,c);
    		return np;
    	}
    	void insert(int id){
    		int last=1;
    		for(int i=1;i<=n;i++) last=append(last,s[i]-'a'),epos[last][id]=1;
    	}
    	void solve(){
    		for(int i=1;i<=tot;i++) c[len[i]]++;
    		for(int i=1;i<N;i++) c[i]+=c[i-1];
    		for(int i=tot;i>=1;i--) a[c[len[i]]--]=i;
    		for(int i=tot;i>1;i--) for(int j=0;j<2;j++) epos[fa[a[i]]][j]+=epos[a[i]][j];
    		int ans=inf;
    		for(int i=2;i<=tot;i++) if(epos[i][0]==1&&epos[i][1]==1) ans=min(ans,len[fa[i]]+1);
    		printf("%d
    ",ans==inf?-1:ans);
    	}
    }sam;
    
    int main(){
    	for(int i=0;i<2;i++){
    		scanf("%s",s+1);
    		n=strlen(s+1);
    		sam.insert(i);
    	}
    	sam.solve();
    	return 0;
    }
    
  • 相关阅读:
    MDL中捕获到损坏的页表页
    跟踪MmSt分页池使用情况
    了解NTFS压缩
    如何跟踪高CPU在用户模式应用程序-现场调试!
    如何与转储文件建立丰富多彩的关系
    Kernel Stack Overflows
    非分页池的消耗
    MBR反汇编
    LPC (Local procedure calls)(二)内核调试扩展
    LPC (Local procedure calls) (一)数据结构
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12670854.html
Copyright © 2020-2023  润新知