DFA自动机.....
http://unbelievable.ycool.com/post.715479.html
DFA是用来做多串匹配的.... 详情还是要看IOI2004ZZY的论文拉....
反正是个很拽很拽的算法拉!!!
我好不容易写了个标程出来....狂兴奋啊......
// 其实这就是05-06-10-4 拉......
反正是个很拽很拽的算法拉!!!
我好不容易写了个标程出来....狂兴奋啊......
// 其实这就是05-06-10-4 拉......
{$R-,I-,Q-,S-} program meteor; const inf='meteor.in'; ouf='meteor.out'; maxn=500000; maxl=100000; type nodetype=record child:array ['a'..'z'] of longint; prefix,num:longint; been:boolean; end; nodest=array [1..maxn] of longint; node=array [1..maxl] of char; var dfa:array [0..maxn] of nodetype; ed:array [0..maxl] of longint; s:node; sp,n,m:longint; procedure build(k:longint); var i,a:longint; temp:char; begin a:=1; repeat read(temp); if dfa[a].child[temp]=0 then begin inc(sp); inc(dfa[a].num); dfa[a].child[temp]:=sp; end; a:=dfa[a].child[temp]; until eoln; readln; ed[k]:=a; end; procedure init; var i:longint; begin assign(input,inf);reset(input); readln(n); for i:=1 to n do read(s[I]); readln; fillchar(dfa,sizeof(dfa),0); sp:=1; dfa[1].been:=false; readln(m); for i:=1 to m do build(i); close(input); end; procedure makeprefix; var temp,h,t,k:longint; st:nodest; i:char; begin fillchar(st,sizeof(st),0); for i:='a' to 'z' do dfa[0].child[I]:=1; h:=0; t:=1; st[1]:=1; dfa[1].prefix:=0; repeat inc(h); temp:=dfa[st[h]].num; for i:='a' to 'z' do begin if temp=0 then break; if dfa[st[h]].child[I]<>0 then begin inc(t); st[t]:=dfa[st[h]].child[I]; dec(temp); k:=dfa[st[h]].prefix; while dfa[k].child[I]=0 do k:=dfa[k].prefix; dfa[st[t]].prefix:=dfa[k].child[I]; end; end; until h=t; end; procedure work; var i,k:longint; t:char; begin dfa[1].been:=true; k:=1; for i:=1 to n do begin while dfa[k].child[s[I]]=0 do k:=dfa[k].prefix; k:=dfa[k].child[s[I]]; dfa[k].been:=true; end; end; procedure out; var i:longint; begin assign(output,ouf);rewrite(output); for i:=1 to m do if dfa[ed[I]].been then writeln('YES') else writeln('NO'); close(output); end; procedure check(k:longint); begin k:=dfa[k].prefix; while not dfa[k].been do begin dfa[k].been:=true; k:=dfa[k].prefix; end; end; procedure dfs(k:longint); var i:char; begin if k=0 then exit; if dfa[k].been then check(k); if dfa[k].num=0 then exit; for i:='a' to 'z' do if dfa[k].child[I]>0 then dfs(dfa[k].child[I]); end; begin init; makeprefix; work; dfs(1); out; end. |