zoukankan      html  css  js  c++  java
  • 【洛谷P3796】(模板)AC自动机(加强版)

    题目链接

    (模板)AC自动机(加强版)

    题目描述

    (N)个由小写字母组成的模式串以及一个文本串(T)。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串(T)中出现的次数最多。

    输入格式

    输入含多组数据。
    每组数据的第一行为一个正整数(N),表示共有(N)个模式串,(1 leq N leq 150)
    接下去(N)行,每行一个长度小于等于(70)的模式串。下一行是一个长度小于等于(10^6)的文本串(T)
    输入结束标志为(N=0)

    输出格式

    对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。

    样例输入

    2
    aba
    bab
    ababababac
    6
    beta
    alpha
    haha
    delta
    dede
    tata
    dedeltalphahahahototatalpha
    0
    

    样例输出

    4
    aba
    2
    alpha
    haha
    

    题解

    这是一道AC自动机板题,
    我们用普通的AC自动机直接做就好了,但是因为这道题要求求出每个模式串在文本串中出现的次数,所以我们还要对字典树上的每个节点记录每个从根到这个节点的模式串是哪一个,在这里我是用(vector)存储的。
    注意:因为有多组数据,所以要注意数据的清空,不要让上一组数据影响到下一组数据
    上代码:

    #include<bits/stdc++.h>
    #include<vector>
    using namespace std;
    int n;
    char c[209][79],cc[1000009];
    int ss[209];
    struct aa{
    	int s;
    	int up;
    	int to[30];
    	vector<int>tt;
    }p[100009];
    int len;
    int ans;
    void add(int x){
    	int l=strlen(c[x]);
    	int u=0;
    	for(int j=0;j<l;j++){
    		if(p[u].to[c[x][j]-'a']) u=p[u].to[c[x][j]-'a'];
    		else {p[u].to[c[x][j]-'a']=++len;u=len;p[len].s=p[len].up=0;memset(p[len].to,0,sizeof(p[len].to));p[len].tt.clear();}
    	}
    	p[u].s++;
    	p[u].tt.push_back(x);
    }
    int q[1000009],l=1,r=0;
    void bfs(){
    	for(int j=0;j<='z'-'a';j++)
    		if(p[0].to[j]) q[++r]=p[0].to[j];
    	while(l<=r){
    		int u=q[l++];
    		for(int j=0;j<='z'-'a';j++){
    			if(p[u].to[j]){
    				p[p[u].to[j]].up=p[p[u].up].to[j];
    				q[++r]=p[u].to[j];
    			}else p[u].to[j]=p[p[u].up].to[j];
    		}
    	}
    }
    int main(){
    	scanf("%d",&n);
    	while(n!=0){
    		memset(ss,0,sizeof(ss));
    		len=0;
    		p[0].s=p[0].up=0;memset(p[0].to,0,sizeof(p[0].to));p[0].tt.clear();
    		for(int j=1;j<=n;j++){
    			scanf("%s",c[j]);
    			add(j);
    		}
    		bfs();
    		scanf("%s",cc);
    		int l=strlen(cc);
    		int uu=0;
    		for(int j=0;j<l;j++){
    			uu=p[uu].to[cc[j]-'a'];
    			int k=uu;
    			while(k){
    				for(int j=0;j<p[k].tt.size();j++)
    					ss[p[k].tt[j]]++;
    				k=p[k].up;
    			}
    		}
    		int mx=0;
    		for(int j=1;j<=n;j++)
    			mx=max(mx,ss[j]);
    		printf("%d
    ",mx);
    		for(int j=1;j<=n;j++)
    			if(ss[j]==mx) printf("%s
    ",c[j]);
    		scanf("%d",&n);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Memcached通信协议
    quartz在集群环境下的最终解决方案
    在中间层 .NET 应用程序中通过授权管理器使用基于角色的安全
    微软MVC框架实战:开源的JS库Knockout
    EL表达式
    Hadoop安装配置
    Memcached安装
    Maven对不同的测试环境用不同的参数进行打包
    项目管理案例:赢与非输之别
    十年WEB技术发展历程
  • 原文地址:https://www.cnblogs.com/linjiale/p/12220585.html
Copyright © 2011-2022 走看看