Luo Gu topic -AC automata

P3808 [template] AC automaton (simple version)

Meaning of the questions:

This question is one of the most naked of AC automatic machine templates, and asked how many pattern string appears in the text string, set directly to the board

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
 using namespace std;
 const int maxn=500010;
 queue<int> q;
 struct AC_Automachine{
     int c[maxn][26],val[maxn],fail[maxn],cnt;
     void ins(char *s){
         int len=strlen(s);int now=0;
         for(int i=0;i<len;i++){
             int v=s[i]-'a';
             if(!c[now][v]) c[now][v]=++cnt;
             now=c[now][v];
         }
        val[now]++;
     }
     void build(){
         for(int i=0;i<26;i++){
             if(c[0][i]){
                 fail[c[0][i]]=0;
                 q.push(c[0][i]);
             } 
         }
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(c[u][i]){
                    fail[c[u][i]]=c[fail[u]][i];
                    q.push(c[u][i]);
                }
                else c[u][i]=c[fail[u]][i];
            }
        }
     }
     int query(char *s){
         int len=strlen(s);
         int now=0,ans=0;
         for(int i=0;i<len;i++){
             now=c[now][s[i]-'a'];
             for(int t=now;t&&~val[t];t=fail[t])
                 years + = val [t] val [t] = - 1 ;
         }
         return ans;
     }
 }AC;
 int n;
 char p[1000005];
 int main()
 {
     scanf("%d",&n);
     for(int i=1;i<=n;i++) scanf("%s",p),AC.ins(p);
     AC.build();
     scanf("%s",p);
     int ans=AC.query(p);
     cout<<ans<<endl;
     return 0;
 }
View Code

P3796 [template] AC automaton enhanced version

Meaning of the questions:

This question is asked which mode is most often, and the output strings occurrences, a plurality of the plurality of outputs, the practice is not difficult, to open a number of occurrences ans [i] array record pattern string i string appears, and then find the maximum , then again ans traversed array output the same maximum value corresponding to the target string. Another point is different for the insert operation to mark the end of each pattern string pattern string of numbers should be changed in order to record an array ans

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
 using namespace std; 
 const int maxn=300000;
 string s[160],temp;
 int ans[maxn],n;
 struct AC_Automachine{
     int c[maxn][26],val[maxn],fail[maxn],cnt;
     void init(){
         memset(c,0,sizeof(c));
         memset(ans,0,sizeof(ans));
         memset(val,0,sizeof(val));
         memset(fail,0,sizeof(fail));
         cnt=0;
     }
     void insert(string s,int k){
         int now=0;
         for(int i=0;i<s.length();i++){
             int v=s[i]-'a';
             if(!c[now][v]) c[now][v]=++cnt;
             now=c[now][v];
         }
        val[now]=k;
     }
    void build(){
        queue<int> q;
        for(int i=0;i<26;i++){
            if(c[0][i]){
                fail[c[0][i]]=0;
                q.push(c[0][i]);
            }
        }
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(c[u][i]){
                    fail[c[u][i]]=c[fail[u]][i];
                    q.push(c[u][i]);
                }
                else c[u][i]=c[fail[u]][i];
            }
        }
    }
    void query(string s){
        int now=0;
        for(int i=0;i<s.length();i++){
            now=c[now][s[i]-'a'];
            for(int t=now;t;t=fail[t])
                years [val [t]] ++ ;
        }
    }
 }AC;
 int main ()
 {
     while(scanf("%d",&n)&&n){
         AC.init();
         for(int i=1;i<=n;i++){
             cin>>s[i];
             AC.insert(s[i],i);
         }
         AC.build();
         cin>>temp;
         AC.query(temp);
         int pos=0;
         for(int i=1;i<=n;i++) pos=max(pos,ans[i]);
         cout<<pos<<endl;
         for(int i=1;i<=n;i++) if(ans[i]==pos) cout<<s[i]<<endl; 
     }
 }
View Code

 

Guess you like

Origin www.cnblogs.com/overrate-wsj/p/12329507.html