AC自动机——HDU2222,HDU5384

HDU2222

HDU5384

两道AC自动机模板题

不过一道是被包含模式串的个数,一道是模式串出现个数

互相改改就行了

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int maxn=1e6+7;
queue<int>q;
struct Ac_automaton{
    int tire[maxn][26],val[maxn],fail[maxn],cnt;
    void init(){
        memset(tire,0,sizeof(tire));
        memset(val,0,sizeof(val));
        cnt=0;
    }
    void ins(char *s){
        int len=strlen(s),rt=0;
        for(int i=0;i<len;i++){
            int id=s[i]-'a';
            if(!tire[rt][id])tire[rt][id]=++cnt;
            rt=tire[rt][id];
        }
        val[rt]++;
    }
    void build(){
        for(int i=0;i<26;i++)
        if(tire[0][i]){
            fail[tire[0][i]]=0;
            q.push(tire[0][i]);
        }
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=0;i<26;i++){
                if(tire[u][i]){
                    fail[tire[u][i]]=tire[fail[u]][i];
                    q.push(tire[u][i]);
                }
                else tire[u][i]=tire[fail[u]][i];
            }
        }
    }
    int query(char *s){
        int len=strlen(s),ans=0,rt=0;
        for(int i=0;i<len;i++){
            int id=s[i]-'a';
            rt=tire[rt][id];
            for(int j=rt;j&&~val[j];j=fail[j]){
                ans+=val[j];
                val[j]=-1;
            }
        }
        return ans;
    }
}AC;
int t,n;
char a[maxn],b[maxn];
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        AC.init();
        for(int i=1;i<=n;i++){
            scanf("%s",a);
            AC.ins(a);
        }
        AC.build();
        scanf("%s",b);
        printf("%d
",AC.query(b));
    }
    return 0;
}
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1e6+7;
queue<int>q;
struct Ac_automaton{
    int tire[maxn][26],val[maxn],fail[maxn],cnt;
    void init(){
        memset(tire,0,sizeof(tire));
        memset(val,0,sizeof(val));
        cnt=0;
    }
    void ins(char *s){
        int len=strlen(s),rt=0;
        for(int i=0;i<len;i++){
            int id=s[i]-'a';
            if(!tire[rt][id])tire[rt][id]=++cnt;
            rt=tire[rt][id];
        }
        val[rt]++;
    }
    void build(){
        for(int i=0;i<26;i++)
        if(tire[0][i]){
            fail[tire[0][i]]=0;
            q.push(tire[0][i]);
        }
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=0;i<26;i++){
                if(tire[u][i]){
                    fail[tire[u][i]]=tire[fail[u]][i];
                    q.push(tire[u][i]);
                }
                else tire[u][i]=tire[fail[u]][i];
            }
        }
    }
    int query(string s){
        int len=s.size(),ans=0,rt=0;
        for(int i=0;i<len;i++){
            int id=s[i]-'a';
            rt=tire[rt][id];
            for(int j=rt;j/*&&~val[j]*/;j=fail[j]){
                ans+=val[j];
                //val[j]=-1;
            }
        }
        return ans;
    }
}AC;
int t,m,n;
string str;
char s[maxn];
vector<string>v;
int main(){
    scanf("%d",&t);
    while(t--){
        AC.init();
        v.clear();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            cin>>str;
            v.push_back(str);
        }
        for(int i=1;i<=m;i++){
            scanf("%s",s);
            AC.ins(s);
        }
        AC.build();
        for(int i=0;i<n;i++){
            printf("%d
",AC.query(v[i]));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/helman/p/11315969.html