• 【BZOJ1030】[JSOI2007]文本生成器


    ...其实暑假的时候写过一次,不过那时候对这道题理解不是很深,所以重写了一遍....

    尝试用新的模版去写,然后发现新的模版里面我把fail并到next,以省去多次的while取点,但是对于这道题,fail是必须用到的,因为要DP...所以不能并进去...于是只能乖乖滚回去写原来的方法,每次都去往回while fail节点...然后就是pd数组的传递,要和fail所连的点保持一直,因为是BFS下来的...

    然后...代码如下

     1 const maxn=6419;
     2  maxs=25;
     3  vv=10007;
     4 var
     5  next:array[0..maxn,0..maxs] of longint;
     6  pd:array[0..maxn] of boolean;
     7  f:array[0..maxn] of longint;
     8  q:array[0..maxn] of longint;
     9  dp:array[0..maxn,0..105] of longint;
    10  s:string;
    11  head,tail,root,n,m,tot:longint;
    12 
    13 procedure push(x:longint); begin inc(tail); q[tail]:=x; end;
    14 
    15 function new:longint;
    16 var i:longint;
    17 begin
    18  pd[tot]:=false;
    19  for i:= 0 to maxs do next[tot,i]:=-1;
    20  inc(tot); exit(tot-1);
    21 end;
    22 
    23 procedure insert(s:string);
    24 var c,i,v:longint;
    25 begin
    26  v:=root;
    27  for i:= 1 to length(s) do
    28   begin
    29    c:=ord(s[i])-65;
    30    if next[v,c]=-1 then next[v,c]:=new;
    31    v:=next[v,c];
    32   end;
    33  pd[v]:=true;
    34 end;
    35 
    36 procedure build;
    37 var v,tmp,i:longint;
    38 begin
    39  f[root]:=root;
    40  head:=1; tail:=0;
    41  for i:= 0 to maxs do
    42   if next[root,i]<>-1 then
    43     begin f[next[root,i]]:=root; push(next[root,i]); end;
    44  while head<=tail do
    45   begin
    46    v:=q[head]; inc(head);
    47    for i:= 0 to maxs do
    48     if next[v,i]<>-1 then
    49      begin
    50       push(next[v,i]);
    51       tmp:=f[v];
    52       while (tmp<>root) and (next[tmp,i]=-1) do tmp:=f[tmp];
    53       if next[tmp,i]<>-1 then tmp:=next[tmp,i];
    54       if tmp=-1 then f[next[v,i]]:=root else f[next[v,i]]:=tmp;
    55       if not pd[next[v,i]] then pd[next[v,i]]:=pd[tmp];
    56      end;
    57   end;
    58 end;
    59 
    60 procedure solve;
    61 var i,j,k,v,cnt,ans:longint;
    62 begin
    63  dp[0,0]:=1;
    64  for i:= 1 to m do
    65   for j:= root to tot do
    66    if (not pd[j]) and (dp[j,i-1]>0) then
    67     for k:= 0 to maxs do
    68      begin
    69       v:=j;
    70       while (next[v,k]=-1) and (v<>root) do v:=f[v];
    71       if next[v,k]<>-1 then v:=next[v,k];
    72       if not pd[v] then dp[v,i]:=(dp[v,i]+dp[j,i-1]) mod vv;
    73      end;
    74  cnt:=0;
    75  for i:= 0 to tot do cnt:=(cnt+dp[i,m]) mod vv;
    76  ans:=1;
    77  for i:= 1 to m do ans:=(ans*26) mod vv;
    78  ans:=(((ans-cnt) mod vv+vv) mod vv);
    79  writeln(ans);
    80 end;
    81 
    82 procedure init;
    83 var i:longint;
    84 begin
    85  readln(n,m);
    86  root:=new;
    87  for i:= 1 to n do
    88   begin
    89    readln(s);
    90    insert(s);
    91   end;
    92  build;
    93 end;
    94 
    95 Begin
    96  init;
    97  solve
    98 End.
  • 相关阅读:
    利用MFC获取网页内容
    IP地址 >实际地址 ,API 查询
    一个小时内学习 SQLite 数据库
    Sqlite c/c++ api 学习
    笔记
    Sqlite的操作(增加,删除,查询,修改)
    免费天气API
    ServerSocketChannel的使用例子
    各种模式一览
    什么事文件描述符
  • 原文地址:https://www.cnblogs.com/EC-Ecstasy/p/4183218.html
Copyright © 2020-2023  润新知