• hdu 3065 AC自动机模版题


    题意:输出每个模式串出现的次数,查询的时候呢使用一个数组进行记录就好。

    同上题一样的关键点,其他没什么难度了。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int maxw = 1000 * 50 + 10;
    const int sigma_size = 128;
    const int maxl = 2000000 + 10;
    
    char str[1010][100];
    
    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]);
    			    }
    		}
    	}
    	int num[1000 + 10];
    	void query(const char *buf,int n){
    		memset(num,0,sizeof(num));
    		int now=root,len=strlen(buf);
    		for(int i=0;i<len;i++){
    			now=next[now][buf[i]];
    			int tmp=now;
    			while(tmp!=root){
    				if(end[tmp]!=-1)
    				    num[end[tmp]]++;
    				tmp=fail[tmp];
    			}
    		}
    		for(int i=0;i<n;i++)
    		  if(num[i])
    		    printf("%s: %d
    ",str[i],num[i]);
    	}
    };
    
    char buf[maxl];
    Trie ac;
    
    int main()
    {
    	int n;
    	while(~scanf("%d",&n)){
    		ac.init();
    		for(int i=1;i<=n;i++){
    			scanf("%s",str[i]);
    			ac.insert(str[i],i);
    		}
    		ac.build();
    		scanf("%s",buf);
    		ac.query(buf,n);
    	}
    	return 0;
    }


     

  • 相关阅读:
    CodeForces
    POJ1113 Wall —— 凸包
    UVA11330 Andy's Shoes —— 置换分解
    FZU2013 A short problem —— 线段树/树状数组 + 前缀和
    fzu月赛 2203 单纵大法好 二分
    codeforces 519E A and B and Lecture Rooms LCA倍增
    hdu 5459 Jesus Is Here (费波纳茨递推)
    zoj 3469 Food Delivery 区间dp + 提前计算费用
    hdu5438 Ponds dfs 2015changchun网络赛
    hdu5432 二分
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3398119.html
走看看 - 开发者的网上家园