absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] BZOJ 1179 Atm
[破碎的状态] BZOJ 3670

[破碎的状态] BZOJ 1030 文本生成器

absi2011 posted @ Apr 19, 2016 03:33:14 PM in 刷题记录 with tags AC自动机 字符串 bzoj 小高考 trie , 548 阅读

AC自动机模版题

似乎要注意如果某个节点x的fail是可接受的,那么x也是可接受的

还有对于root的child的fail要特判强制扔到root上

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<time.h>
#include<bitset>
#include<vector>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    bool accept;
    int val1;
    int val2;
    node * ch[26];
    node * fail;
};
char a[105];
node * new_node()
{
    static node a[100005];
    static int top=0;
    memset(a[top].ch,0,sizeof(a[top].ch));
    a[top].fail=0;
    a[top].accept=false;
    return &a[top++];
}
const int modo=10007;
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d",&n,&m);
    int i;
    node * root=new_node();
    for (i=0;i<n;i++)
    {
        scanf("%s",a);
        int j;
        node * now=root;
        for (j=0;a[j]!='\0';j++)
        {
            if (now->ch[a[j]-'A']==0)
            {
                now->ch[a[j]-'A']=new_node();
            }
            now=now->ch[a[j]-'A'];
        }
        now->accept=true;
    }
    static node * que[6005];
    int front=0,rail=1;
    que[0]=root;
    for (;front<rail;front++)
    {
        int i;
        for (i=0;i<26;i++)
        {
            if (que[front]->ch[i]==0) continue;
            que[rail++]=que[front]->ch[i];
        }
    }
    root->fail=root;
    for (i=0;i<26;i++)
    {
        if (root->ch[i]==0) root->ch[i]=root;
    }
    for (i=0;i<rail;i++)
    {
        int j;
        node * t=que[i];
        for (j=0;j<26;j++)
        {
            if (t->ch[j]==0)
            {
                t->ch[j]=t->fail->ch[j];
            }
            else
            {
                t->ch[j]->fail=t->fail->ch[j];
                if (t==root) t->ch[j]->fail=root;
                if (t->ch[j]->fail->accept) t->ch[j]->accept=true;
            }
        }
    }
    root->val2=1;
    int p=1;
    for (i=0;i<m;i++)
    {
        p*=26;
        p%=modo;
        int j;
        for (j=0;j<rail;j++)
        {
            que[j]->val1=que[j]->val2%modo;
            que[j]->val2=0;
        }
        for (j=0;j<rail;j++)
        {
            if (que[j]->accept) continue;
            int k;
            for (k=0;k<26;k++)
            {
                que[j]->ch[k]->val2+=que[j]->val1;
            }
        }
    }
    for (i=0;i<rail;i++)
    {
        if (que[i]->accept) continue;
        p-=que[i]->val2;
        p%=modo;
    }
    p+=modo;
    printf("%d\n",p%modo);
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter