[破碎的状态] BZOJ 1030 文本生成器
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;
}
评论 (0)