• hdu 2896 AC自动机模版题


    题意:输出出现模式串的id,还是用end记录id就可以了。

    本题有个关键点:“以上字符串中字符都是ASCII码可见字符(不包括回车)。”  -----也就说AC自动机的Trie树需要128个单词分支。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int maxw = 210 *500 + 10;
    const int sigma_size = 128;
    const int maxl = 10000 + 10;
    
    struct Trie{
    	int next[maxw][sigma_size],fail[maxw],end[maxw];
    	int root,L;
    	int newnode(){
    		for(int i=0;i<sigma_size;i++)
    		    next[L][i]=-1;
    		end[L++]=-1;
    		return L-1;
    	}
    	void init(){
    		L=0;
    		root=newnode();
    	}
    	void insert(const char *s,int id){
    		int now=root,len=strlen(s);
    		for(int i=0;i<len;i++){
    			if(next[now][s[i]]==-1)
    			    next[now][s[i]]=newnode();
    			now=next[now][s[i]];
    		}
    		end[now]=id;
    	}
    	void build(){
    		queue<int>Q;
    		fail[root]=root;
    		for(int i=0;i<sigma_size;i++)
    		    if(next[root][i]==-1)
    		        next[root][i]=root;
    		    else{
    		    	fail[next[root][i]]=root;
    		    	Q.push(next[root][i]);
    		    }
    		while(!Q.empty()){
    			int now=Q.front();
    			Q.pop();
    			for(int i=0;i<sigma_size;i++)
    			    if(next[now][i]==-1)
    			        next[now][i]=next[fail[now]][i];
    			    else{
    			    	fail[next[now][i]]=next[fail[now]][i];
    			    	Q.push(next[now][i]);
    			    }
    		}
    	}
    	bool used[500 + 10];
    	bool query(const char *buf,int n,int id){
    		int now=root,len=strlen(buf);
    		memset(used,false,sizeof(used));
    		bool flag =false;
    		for(int i=0;i<len;i++){
    			now=next[now][buf[i]];
    			int tmp=now;
    			while(tmp!=root){
    				if(end[tmp]!=-1){
    					used[end[tmp]]=true;
    					flag=true;
    				}
    			tmp=fail[tmp];
    			}
    		}
    		if(!flag) return false;
    		printf("web %d:",id);
    		for(int i=1;i<=n;i++)
    		    if(used[i])    printf(" %d",i);
    		printf("
    ");
    		return true;
    	}
    };
    
    char buf[maxl];
    Trie ac;
    
    int main()
    {
    	int n,m;
    	while(~scanf("%d",&n)){
    		ac.init();
    		for(int i=1;i<=n;i++){
    			scanf("%s",buf);
    			ac.insert(buf,i);
    		}
    		ac.build();
    		int ans=0;
    		scanf("%d",&m);
    		for(int i=1;i<=m;i++){
    			scanf("%s",buf);
    			if(ac.query(buf,n,i))  ans++;
    		}
    		printf("total: %d
    ",ans);
    	}
    	return 0;
    }


     

  • 相关阅读:
    audio之点击图标切换音频播放状态以及替换当前图标
    js之ajax的封装
    JavaScript之ajax的作用、流程以及如何设置请求头
    BFC的理解
    2016年总结
    如何用shared_ptr减少锁的争用
    webrtc初识
    2015总结与2016展望
    记一次程序排错与std::getline
    spawn协程学习
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3398142.html
Copyright © 2020-2023  润新知