• P3796 【模板】AC自动机(加强版)


    P3796 【模板】AC自动机(加强版)

    https://www.luogu.org/problemnew/show/P3796

    题目描述

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

    输入输出格式

    输入格式:

    输入含多组数据。

    每组数据的第一行为一个正整数NN,表示共有NN个模式串,1 leq N leq 1501N150。

    接下去NN行,每行一个长度小于等于7070的模式串。下一行是一个长度小于等于10^6106的文本串TT。

    输入结束标志为N=0N=0。

    输出格式:

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

    输入输出样例

    输入样例#1: 
    2
    aba
    bab
    ababababac
    6
    beta
    alpha
    haha
    delta
    dede
    tata
    dedeltalphahahahototatalpha
    0
    输出样例#1: 
    4
    aba
    2
    alpha
    haha
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define lson l,mid,rt<<1
      4 #define rson mid+1,r,rt<<1|1
      5 #define sqr(x) ((x)*(x))
      6 #define maxn 1000005
      7 typedef long long ll;
      8 typedef unsigned long long ull;
      9 const ull MOD=257;
     10 /*#ifndef ONLINE_JUDGE
     11         freopen("1.txt","r",stdin);
     12 #endif */
     13 
     14 struct tree{
     15     int fail;
     16     int vis[26];
     17     int num;
     18 }ac[1000005];
     19 
     20 int cnt=0;
     21 
     22 struct ANS{
     23     int num,pos;
     24     bool operator<(const ANS &b){
     25         if(num==b.num) return pos<b.pos;
     26         return num>b.num;
     27     }
     28 }ans[155];
     29 
     30 void Clear(int x){
     31     memset(ac[x].vis,0,sizeof(ac[0].vis));
     32     ac[x].num=ac[x].fail=0;
     33 }
     34 
     35 void build(string s,int flag){///建trie树
     36     int len=s.length();
     37     int now=0;
     38     for(int i=0;i<len;i++){
     39         if(ac[now].vis[s[i]-'a']==0){
     40             ac[now].vis[s[i]-'a']=++cnt;
     41             Clear(cnt);
     42         }
     43         now=ac[now].vis[s[i]-'a'];
     44     }
     45     ac[now].num=flag;
     46 }
     47 
     48 void get_fail(){///构建成trie图
     49     queue<int>Q;
     50     ac[0].fail=0;
     51     for(int i=0;i<26;i++){
     52         if(ac[0].vis[i]){
     53             ac[ac[0].vis[i]].fail=0;
     54             Q.push(ac[0].vis[i]);
     55         }
     56     }
     57     while(!Q.empty()){
     58         int u=Q.front();
     59         Q.pop();
     60         for(int i=0;i<26;i++){
     61             if(ac[u].vis[i]){
     62                 ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i];
     63                 Q.push(ac[u].vis[i]);
     64             }
     65             else{
     66                 ac[u].vis[i]=ac[ac[u].fail].vis[i];///如果当前结点不存在,就指向父亲结点的fail指向的结点的子结点
     67             }
     68         }
     69     }
     70 }
     71 
     72 void ac_query(string s){
     73     int len=s.length();
     74     int now=0;
     75     for(int i=0;i<len;i++){
     76         now=ac[now].vis[s[i]-'a'];
     77         for(int t=now;t&&ac[t].num!=-1;t=ac[t].fail){
     78             ans[ac[t].num].num++;
     79         }
     80     }
     81 }
     82 
     83 string s[155];
     84 
     85 int main(){
     86     #ifndef ONLINE_JUDGE
     87         freopen("1.txt","r",stdin);
     88     #endif
     89     std::ios::sync_with_stdio(false);
     90     int n;
     91     while(cin>>n){
     92         if(!n) break;
     93         Clear(0);
     94         for(int i=1;i<=n;i++){
     95             cin>>s[i];
     96             build(s[i],i);
     97             ans[i].num=0;
     98             ans[i].pos=i;
     99         }
    100         get_fail();
    101         cin>>s[0];
    102         ac_query(s[0]);
    103         sort(ans+1,ans+n+1);
    104         cout<<ans[1].num<<endl;
    105         cout<<s[ans[1].pos]<<endl;
    106         for(int i=2;i<=n;i++){
    107             if(ans[i].num==ans[i-1].num){
    108                 cout<<s[ans[i].pos]<<endl;
    109             }
    110             else{
    111                 break;
    112             }
    113         }
    114     }
    115 }
    View Code
  • 相关阅读:
    oracle中varchar2和nvarchar2的区别
    Hbuilder与夜神连接
    BUILD 2015: Visual Studio对GitHub的支持
    Visual Studio Developer Assistant 3月新功能展示
    Visual Studio 发布新版API智能提示
    微软发布手机版 Sample Browser。7000多示例代码一手掌握
    微软 PowerShell Script Explorer 满血复活,正式发布
    IBM的“认知计算时代”
    最新 Windows 10 应用项目模板发布
    Windows 10四大版本区别详解:家庭版, 专业版, 企业版和教育版
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/10363717.html
Copyright © 2020-2023  润新知