HIT暑期集训 AC自动机

贴一个网上讲AC自动机的博客

一个带图的AC自动机讲解博客

AC自动机模板(插入模式串,输出文本串中模式串出现的次数)

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define maxn 1000100
using namespace std;
struct node
{
    int ch[30],vis,fail,num;
}t[500100];
int cnt;
queue<int>q;
void insert(char s[])
{
    int i,v,u=1,len=strlen(s);
    for (i=0;i<len;i++)
    {
        v=s[i]-'a';
        if (!t[u].ch[v]) t[u].ch[v]=++cnt;
        u=t[u].ch[v];
    }
    t[u].num++;
}
void getFail()
{
    int i,u,v,fl;
    for (i=0;i<26;i++) t[0].ch[i]=1;        
    q.push(1);
    t[1].fail=0;            
    while (!q.empty())
    {
        u=q.front();
        q.pop();
        for (i=0;i<26;i++)
        {            
            v=t[u].ch[i];        
            fl=t[u].fail;    
            if (!v)
            {
                t[u].ch[i]=t[fl].ch[i];
                continue;
            }
            t[v].fail=t[fl].ch[i];
            q.push(v);    
        }
    }
}
int query(char s[])
{
    int i,v,u=1,k,ans=0,len=strlen(s);
    for (i=0;i<len;i++)
    {
        v=s[i]-'a';
        k=t[u].ch[v];    
        while (k>1 && !t[k].vis)
        {
            ans+=t[k].num;
            t[k].vis=1;    
            k=t[k].fail;        
        }
        u=t[u].ch[v];    
    }
    return ans;
}
int main()
{
    int i,T,n;
    char s[maxn];
    scanf("%d",&T);      
    while (T--)
    {
        cnt=1;   
        memset(t,0,sizeof(t));
        scanf("%d",&n);
        for (i=0;i<n;i++) 
        {
            scanf("%s",s);
            insert(s);
        }
        getFail();
        scanf("%s",s);
        printf("%d\n",query(s));
    }
    return 0;
}
AC自动机模板

B    HDU 6096

C    LibreOJ 10062

AC自动机+dfs(还有一些细节需要搞清楚)

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define maxn 30005
using namespace std;
struct node
{
    int ch[2],fail,num;
}t[maxn];
int cnt,vis[maxn],flag;
queue<int>q;
void insert(char s[])
{
    int i,v,u=1,len=strlen(s);
    for (i=0;i<len;i++)
    {
        v=s[i]-'0';
        if (!t[u].ch[v]) t[u].ch[v]=++cnt;
        u=t[u].ch[v];
    }
    t[u].num=1;
}
void getFail()
{
    int i,u,v,fl;
    for (i=0;i<2;i++) t[0].ch[i]=1;        
    q.push(1);
    t[1].fail=0;            
    while (!q.empty())
    {
        u=q.front();
        q.pop();
        if (t[t[u].fail].num) t[u].num=t[t[u].fail].num;
        for (i=0;i<2;i++)
        {            
            v=t[u].ch[i];        
             fl=t[u].fail;    
            if (!v)
            {
                t[u].ch[i]=t[fl].ch[i];
                continue;
            }
            t[v].fail=t[fl].ch[i];
            
            q.push(v);    
        }
    }
}
void dfs(int x)
{
    if (vis[x]) 
    {
        flag=1;
        return;
    }
    if (flag || t[x].num) return;
    t[x].num=1;vis[x]=1;
    dfs(t[x].ch[0]);
    dfs(t[x].ch[1]);
    vis[x]=0;
}
int main()
{
    int i,j,k,n;
    char s[maxn];
    scanf("%d",&n);
    cnt=1;   
    for (i=0;i<n;i++) 
    {
        scanf("%s",s);
        insert(s);
    }
    getFail();
    flag=0;
    dfs(1);
    if (flag) printf("TAK\n");
    else printf("NIE\n");
    return 0;
}

 

D    LibreOJ 10063

AC自动机+动规

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define mod 10007
using namespace std;
struct node
{
    int ch[30],vis,fail,num;
}t[60010];
int cnt,f[60010][105];
queue<int>q;
void insert(char s[])
{
    int i,v,u=1,len=strlen(s);
    for (i=0;i<len;i++)
    {
        v=s[i]-'A';
        if (!t[u].ch[v]) t[u].ch[v]=++cnt;
        u=t[u].ch[v];
    }
    t[u].num=1;
}
void getFail()
{
    int i,u,v,fl;
    for (i=0;i<26;i++) t[0].ch[i]=1;        
    q.push(1);
    t[1].fail=0;            
    while (!q.empty())
    {
        u=q.front();
        q.pop();
        fl=t[u].fail;
        for (i=0;i<26;i++)
        {            
            v=t[u].ch[i];        
                
            if (!v)
            {
                t[u].ch[i]=t[fl].ch[i];
                continue;
            }
            t[v].fail=t[fl].ch[i];
            q.push(v);    
        }
        if (t[fl].num) t[u].num=1;
    }
}
int main()
{
    int i,j,k,n,m,v,ans=1;
    char s[105];
    cnt=1;
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)    
    {
        scanf("%s",s);
        insert(s);
    }  
    getFail();
    for (i=1;i<=m;i++) ans=(ans*26)%mod;
    f[1][0]=1;
    for (j=1;j<=m;j++)
    for (i=1;i<=cnt;i++)
    {
        if (!f[i][j-1]) continue;
        for (k=0;k<26;k++)
        {
            v=t[i].ch[k];
            if (t[v].num) continue;
            f[v][j]=(f[v][j]+f[i][j-1])%mod;
        }
    }
    for (i=1;i<=cnt;i++) ans=(ans-f[i][m]+mod)%mod;
    printf("%d\n",ans);
    return 0;
}

 

G    计蒜客 T2372

posted @ 2020-08-10 10:36  lsy_kk  阅读(156)  评论(0编辑  收藏  举报