zoukankan      html  css  js  c++  java
  • 洛谷.3121.审查(AC自动机 链表)

    题目链接

    //删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len)) 
    #include <cstdio>
    #include <cstring>
    #define S 26
    const int N=1e5+7;
    
    int n;
    char s[N],p[N];
    struct AC_Automaton
    {
    	int cnt,son[N][S],fail[N],pos[N],q[N],dep[N];
    	bool val[N];
    	struct List
    	{
    		int l,r;
    	}lst[N];
    	void Insert(char *s)
    	{
    		int x=0;
    		for(int i=0,l=strlen(s),id; i<l; ++i)
    		{
    			id=s[i]-'a';
    			if(!son[x][id]) son[x][id]=++cnt,dep[cnt]=dep[x]+1;//这里改用一个局部int ++dep还要更慢。。大概是重复节点很多的原因 
    			x=son[x][id];
    		}
    		val[x]=1;
    	}
    	void Build()
    	{
    		int h=0,t=0;
    		for(int i=0; i<S; ++i)
    			if(son[0][i]) fail[son[0][i]]=0, q[t++]=son[0][i];
    		while(h<t)
    		{
    			int x=q[h++];
    			for(int i=0; i<S; ++i)
    				if(son[x][i]) fail[son[x][i]]=son[fail[x]][i],q[t++]=son[x][i];
    				else son[x][i]=son[fail[x]][i];
    		}
    	}
    	void Query(char *s)
    	{
    		int l=strlen(s+1);
    		for(int i=1; i<l; ++i) lst[i].l=i-1,lst[i].r=i+1;
    		lst[0].r=1, lst[l].l=l-1;
    		for(int x=0,t,i=1; i; i=lst[i].r)
    		{
    			if(son[x][t=s[i]-'a']) 
    			{
    				x=son[x][t];
    				if(val[x])
    				{
    					t=i;
    					for(int j=dep[x]; j; --j) t=lst[t].l;
    					lst[t].r=lst[i].r, lst[lst[i].r].l=t;
    					x=pos[t];
    				}
    			}
    			else x=0;//not x=fail[x]!
    			pos[i]=x;
    		}
    		for(int i=lst[0].r; i; i=lst[i].r) printf("%c",s[i]);
    	}
    }ac;
    
    int main()
    {
    	scanf("%s%d",p+1,&n);
    	for(int i=1; i<=n; ++i) scanf("%s",s),ac.Insert(s);
    	ac.Build(), ac.Query(p);
    	return 0;
    }
    
  • 相关阅读:
    VS中,如何将存在于解决方案里,但是没有显示出来的文件(或文件夹)显示到项目中。
    (转)分布式系统编程,你到哪一级了?
    领域驱动架构学习总结
    Java多线程总结
    MySQL更新优化
    MySQL查询优化
    MySQL索引
    MySQL优化
    MySQL联接操作
    MySQL架构
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8543861.html
Copyright © 2011-2022 走看看