zoukankan      html  css  js  c++  java
  • UVALive-4670 Dominating Patterns(AC自动机)

    题目大意:找出出现次数最多的模式串。

    题目分析:AC自动机裸题。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<map>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=20000;
    
    int ch[N][26];
    string p[155];
    char s[N*50+5];
    int val[N];
    int t[155];
    int f[N+5];
    int last[N+5];
    map<string,int>mp;
    map<int,string>mpp;
    
    struct AC
    {
    	int cnt;
    	void init()
    	{
    		cnt=0;
    		memset(val,0,sizeof(val));
    		memset(ch,0,sizeof(ch));
    		memset(t,0,sizeof(t));
    	}
    	
    	void insert(string str,int v)
    	{
    		int n=str.size();
    		int root=0;
    		for(int i=0;i<n;++i){
    			int c=str[i]-'a';
    			if(!ch[root][c])
    				ch[root][c]=++cnt;
    			root=ch[root][c];
    		}
    		val[cnt]=v;
    	}
    	
    	void getFail()
    	{
    		queue<int>q;
    		f[0]=0;
    		for(int i=0;i<26;++i){
    			int u=ch[0][i];
    			if(!u) continue;
    			f[u]=0;
    			q.push(u);
    			last[u]=0;
    		}
    		while(!q.empty()){
    			int r=q.front();
    			q.pop();
    			for(int i=0;i<26;++i){
    				int u=ch[r][i];
    				if(!u) continue;
    				q.push(u);
    				int v=f[r];
    				while(v&&!ch[v][i]) v=f[v];
    				f[u]=ch[v][i];
    				last[u]=val[f[u]]?f[u]:last[f[u]];
    			}
    		}
    	}
    	
    	void ac(char *s)
    	{
    		int n=strlen(s);
    		int j=0;
    		for(int i=0;i<n;++i){
    			int c=s[i]-'a';
    			while(j&&!ch[j][c]) j=f[j];
    			j=ch[j][c];
    			if(val[j]) getResult(j);
    			else if(last[j]) getResult(last[j]);
    		}
    	}
    	
    	void getResult(int u)
    	{
    		if(u==0) return ;
    		if(u) ++t[val[u]];
    		getResult(last[u]);
    	}
    }ac;
    
    int main()
    {
    	int n;
    	while(~scanf("%d",&n)&&n)
    	{
    		ac.init();
    		int cnt=0;
    		mp.clear();
    		mpp.clear();
    		for(int i=0;i<n;++i){
    			cin>>p[i];
    			if(mp[p[i]]==0) mp[p[i]]=++cnt;
    			ac.insert(p[i],cnt);
    			mpp[cnt]=p[i];
    		}
    		scanf("%s",s);
    		
    		ac.getFail();
    		ac.ac(s);
    		int maxn=0;
    		for(int i=1;i<=cnt;++i)
    			maxn=max(maxn,t[i]);
    		cout<<maxn<<endl;
    		for(int i=1;i<=cnt;++i)
    			if(t[i]==maxn) cout<<mpp[i]<<endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    数据结构与算法
    c++学习笔记
    红黑树(map与unorder_map)B B+树
    数据库笔记
    多路复用IO:select poll epoll
    https加密过程!!! 这才是差不多非常详细的https双方获取共用的秘钥过程!!!!!
    助教周报(第一轮)——范青青
    第二十二周助教总结(2021.6.28-7.4)
    第二十一周助教总结(2021.6.21-6.27)
    第二十周助教总结(2021.6.14-6.20)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5752840.html
Copyright © 2011-2022 走看看