您的位置:首页 > 其它

[DP+AC自动机] BZOJ1212: [HNOI2004]L语言

2017-11-26 16:33 483 查看
直接 DP,fi 表示前 i 个是否合法。fi|=fi−len(aj)(s[i−len(aj)+1]=aj)

用AC自动机加速转移的匹配过程。

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100005;
int a[maxn];
struct node{
node *ch[26],*fail,*last; vector<int> lst;
node(node* son=NULL){ for(int i=0;i<=25;i++) ch[i]=son; lst.clear(); fail=last=son; }
} nil, *null=&nil, *root=null;
typedef node* P_node;
void Insert(char *now,P_node &p,int _len){
if(p==null) p=new node(null);
if((*now)==0){ p->lst.push_back(_len); return; }
Insert(now+1,p->ch[(*now)-'a'],_len);
}
void Build_AC(){
static queue<P_node> Q;
root->fail=root->last=root;
for(int i=0;i<=25;i++) if(root->ch[i]!=null){
P_node v=root->ch[i]; Q.push(v);
v->fail=v->last=root;
} else root->ch[i]=root;
while(!Q.empty()){
P_node p=Q.front(); Q.pop();
for(int i=0;i<=25;i++) if(p->ch[i]!=null){
P_node v=p->ch[i]; Q.push(v);
v->fail=p->fail->ch[i]; v->last=(v->fail->lst.empty()?v->fail->last:v->fail);
} else p->ch[i]=p->fail->ch[i];
}
}
char st[1100000];
int n,m,f[1100000],ans;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",st), Insert(st,root,strlen(st));
Build_AC();
while(m--){
scanf("%s",st); int len=strlen(st);
for(int i=0;i<=len;i++) f[i]=0; f[0]=1;
P_node p=root; ans=0;
for(int i=1;i<=len;i++){
p=p->ch[st[i-1]-'a'];
for(P_node t=p;t!=root;t=t->last)
for(int j=0;j<t->lst.size();j++) f[i]|=f[i-t->lst[j]];
if(f[i]) ans=i;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: