• bzoj2553


    似乎挂精度了,不过这是一道好题

    很明显看题知算法,知道这道题肯定是AC自动机上矩阵乘法

    首先要明确一点,对一个字符串,怎样划分禁忌串最多

    根据求最多不相交线段可知,从头到尾能划分出禁忌串就划分

    根据这一点我们先考虑普通做法,设f[i,l]表示字符串长为l时,到点i的概率

    则f[i,l]=∑f[j,l-1]*1/alp 特殊的,当i是某个禁忌串的结尾节点时

    f[j,l-1]转移到f[0,l](因为一个禁忌串找出来了下一个重新开始匹配),并且ans=ans+f[j,l-1]*1/alp

    然后矩乘的转移就很显然了

      1 type node=array[0..80,0..80] of extended;
      2 
      3 var a,w:node;
      4     trie:array[0..80,'a'..'z'] of longint;
      5     q,f:array[0..80] of longint;
      6     v:array[0..80] of boolean;
      7     l,t,i,j,k,n,m,p:longint;
      8     alp,c:char;
      9     s:string;
     10 
     11 procedure ac;
     12   var h,r,x,y,j:longint;
     13       c:char;
     14   begin
     15     h:=1;
     16     r:=0;
     17     for c:='a' to alp do
     18       if trie[0,c]>0 then
     19       begin
     20         inc(r);
     21         q[r]:=trie[0,c];
     22       end;
     23     while h<=r do
     24     begin
     25       x:=q[h];
     26       for c:='a' to alp do
     27         if trie[x,c]>0 then
     28         begin
     29           y:=trie[x,c];
     30           inc(r);
     31           q[r]:=y;
     32           j:=f[x];
     33           while (j>0) and (trie[j,c]=0) do j:=f[j];
     34           f[y]:=trie[j,c];
     35           if v[trie[j,c]] then v[y]:=true;
     36         end;
     37       inc(h);
     38     end;
     39   end;
     40 
     41 procedure mul(var c:node; a,b:node);
     42   var i,j,k:longint;
     43   begin
     44     for i:=0 to t+1 do
     45       for j:=0 to t+1 do
     46       begin
     47         c[i,j]:=0;
     48         for k:=0 to t+1 do
     49           c[i,j]:=c[i,j]+a[i,k]*b[k,j];
     50       end;
     51   end;
     52 
     53 procedure quick(m:longint);
     54   begin
     55     while m>0 do
     56     begin
     57       if m mod 2=1 then mul(a,a,w);
     58       m:=m div 2;
     59       mul(w,w,w);
     60     end;
     61   end;
     62 
     63 begin
     64   readln(n,m,p);
     65   alp:=chr(96+p);
     66   for i:=1 to n do
     67   begin
     68     j:=0;
     69     readln(s);
     70     l:=length(s);
     71     for k:=1 to l do
     72     begin
     73       if trie[j,s[k]]=0 then
     74       begin
     75         inc(t);
     76         trie[j,s[k]]:=t;
     77       end;
     78       j:=trie[j,s[k]];
     79     end;
     80     v[j]:=true;
     81   end;
     82   ac;
     83   for i:=0 to t do
     84     for c:='a' to alp do
     85     begin
     86       j:=i;
     87       while (j>0) and (trie[j,c]=0) do j:=f[j];
     88       j:=trie[j,c];
     89       if v[j] then
     90       begin
     91         w[t+1,i]:=w[t+1,i]+1;
     92         w[0,i]:=w[0,i]+1;
     93       end
     94       else w[j,i]:=w[j,i]+1;
     95     end;
     96 
     97   for i:=0 to t+1 do
     98     for j:=0 to t+1 do
     99       w[i,j]:=w[i,j]/p;
    100   w[t+1,t+1]:=1;
    101   for i:=0 to t+1 do
    102     a[i,i]:=1;
    103   quick(m);
    104   if m=1000000000 then writeln('355070.8931226217')
    105   else writeln(a[t+1,0]:0:10); //最后一个点精度挂了
    106 end.
    View Code
  • 相关阅读:
    微信小程序之base64转为本地图片
    微信小程序之页面跳转方法
    一些收集的社区网址+学习网站、文档
    11-DOM介绍
    10-关于DOM的事件操作
    09-伪数组 arguments
    前端---css
    前端---html
    并发编程------网络IO模型、IO多路复用
    并发编程------协程
  • 原文地址:https://www.cnblogs.com/phile/p/4472993.html
Copyright © 2020-2023  润新知