zoukankan      html  css  js  c++  java
  • 模板—字符串—广义后缀自动机

    模板—字符串—广义后缀自动机

    Code(假广义后缀自动机):

    #include <bits/stdc++.h>
    using namespace std;
    #define N 100010
    map <int,int> son[N<<1]; char str[N]; int n;
    int tot=1,last=1,pre[N<<1],dis[N<<1],type[N<<1],many[N<<1],kind[N<<1];
    namespace Sam
    {
    	void pushup(int p,int x) {while(p&&type[p]!=x) many[p]++,type[p]=x,p=pre[p];}
    	void insert(int x,int Tim)
    	{
    		int p=last,np=last=++tot; dis[np]=dis[p]+1,kind[np]=Tim;
    		while(p&&!son[p][x]) son[p][x]=np,p=pre[p];
    		if(!p) {pre[np]=1,pushup(np,Tim);return;} int q=son[p][x];
    		if(dis[q]==dis[p]+1) {pre[np]=q,pushup(np,Tim);return;} int nq=++tot;
    		dis[nq]=dis[p]+1,son[nq]=son[q],pre[nq]=pre[q];
    		type[nq]=type[q],many[nq]=many[q],pre[q]=pre[np]=nq;
    		while(p&&son[p][x]==q) son[p][x]=nq,p=pre[p]; pushup(np,Tim);
    	}
    }
    using namespace Sam;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1,len;i<=n;i++)
    	{
    		scanf("%s",str+1),len=strlen(str+1),last=1;
    		for(int j=1;j<=len;j++) insert(str[j]-'a',i);
    	}
    }
    

    Code(真广义后缀自动机):

    #include <bits/stdc++.h>
    using namespace std;
    #define N 100010
    map <int,int> son[N<<1]; char str[N]; int n;
    int tot=1,last=1,pre[N<<1],dis[N<<1];
    namespace Sam
    {
    	void insert(int x,int Tim)
    	{
    		int p=last,np=last=++tot; 
    		if(son[p][x])
    		{
    			int q=son[p][x]; if(dis[q]==dis[p]+1) last=q;
    			else
    			{
    				int nq=++tot; last=nq;
    				pre[nq]=pre[q],dis[nq]=dis[p]+1;
    				pre[q]=nq,son[nq]=son[q];
    				while(p&&son[p][x]==q) son[p][x]=nq,p=pre[p];
    			}
    		}
    		dis[np]=dis[p]+1;
    		while(p&&!son[p][x]) son[p][x]=np,p=pre[p];
    		if(!p) {pre[np]=1;return;} int q=son[p][x];
    		if(dis[q]==dis[p]+1) {pre[np]=q;return;} int nq=++tot;
    		dis[nq]=dis[p]+1,son[nq]=son[q],pre[nq]=pre[q],pre[q]=pre[np]=nq;
    		while(p&&son[p][x]==q) son[p][x]=nq,p=pre[p];
    	}
    }
    using namespace Sam;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1,len;i<=n;i++)
    	{
    		scanf("%s",str+1),len=strlen(str+1),last=1;
    		for(int j=1;j<=len;j++) insert(str[j]-'a',i);
    	}
    }
    

      

  • 相关阅读:
    单一职责原则
    算法的设计与分析 -----图 (1)
    交换机
    子网掩码
    IP地址分类+网络号
    网络参考模型与5G协议
    什么是5G
    RxJAVA
    EventBus3.0的学习
    ButterKnife+Zelezny插件
  • 原文地址:https://www.cnblogs.com/yangsongyi/p/10653754.html
Copyright © 2011-2022 走看看