zoukankan      html  css  js  c++  java
  • [USACO15FEB]审查(黄金)Censoring (Gold)

    AC自动机在预处理fail的时候预处理下节点对应的匹配串的长度

    这样复杂度就是严格(Theta(n))

    只需要一个栈,在trie图上跑就可以了

    #include"cstdio"
    #include"cstring"
    #include"iostream"
    #include"algorithm"
    using namespace std;
    
    const int MAXN=1e5+5;
    const int siz=26;
    
    int n,cnt;
    int q[MAXN],id[MAXN];
    char s[MAXN],ch[MAXN],stk[MAXN];
    struct Trie{
    	int vis,fail,dep,val;
    	int sn[siz];
    }T[MAXN];
    
    void ins(char *ch)
    {
    	int ln=strlen(ch+1),nw=0;
    	for(int i=1;i<=ln;++i){
    		if(!T[nw].sn[ch[i]-'a']) T[nw].sn[ch[i]-'a']=++cnt,T[cnt].dep=T[nw].dep+1;
    		nw=T[nw].sn[ch[i]-'a'];
    	}++T[nw].vis,T[nw].val=T[nw].dep;
    	return;
    }
    
    void Getfail()
    {
    	int hd=1,tl=0;
    	for(int i=0;i<siz;++i) if(T[0].sn[i]) q[++tl]=T[0].sn[i];
    	while(hd<=tl){
    		int nw=q[hd++];
    		T[nw].val=max(T[nw].val,T[T[nw].fail].val);
    		for(int i=0;i<siz;++i){
    			if(T[nw].sn[i]){
    				T[T[nw].sn[i]].fail=T[T[nw].fail].sn[i];
    				q[++tl]=T[nw].sn[i];
    			}else T[nw].sn[i]=T[T[nw].fail].sn[i];
    		}
    	}return;
    }
    
    void slv(char *ch)
    {
    	int ln=strlen(ch+1),ct=0;
    	for(int i=1;i<=ln;++i){
    		stk[++ct]=ch[i];
    		id[ct]=T[id[ct-1]].sn[ch[i]-'a'];
    		ct-=T[id[ct]].val;
    	}for(int i=1;i<=ct;++i) putchar(stk[i]);
    	puts("");
    	return;
    }
    
    int main()
    {
    	scanf("%s",s+1);
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) scanf("%s",ch+1),ins(ch);
    	Getfail();slv(s);
    	return 0;
    }
    
  • 相关阅读:
    Java 字符串,byte[],16进制的字符串互转
    Java中char的字节数
    有向图 获取回路转
    java字符串分割处理split及特殊符号 转
    java如何直接跳出外层循环 标签
    求有向图中两点间所有路径
    五周突破N1 第五周第三单元
    5周突破N1 惯用句 1
    5周N1 300P
    5周突破N
  • 原文地址:https://www.cnblogs.com/AH2002/p/10059470.html
Copyright © 2011-2022 走看看