bzoj1444

显然自动机上高斯消元
根据AC自动机上的转移可以列出一系列方程
但这个样的方程解出来全0是一组解
说明有线性组合的情况
考虑除非没人能赢,否则每个人赢的概率和为1
那么我们只要把原来的第一个方程换成这个即可

  1 var ans,d:array[0..110] of double;
  2     a:array[0..110,0..110] of double;
  3     w,q,f:array[0..110] of longint;
  4     trie:array[0..110,0..26] of longint;
  5     v:array[0..110] of boolean;
  6     j,k,i,n,m,l,x,y,t:longint;
  7     s:string;
  8 
  9 procedure swap(var a,b:double);
 10   var c:double;
 11   begin
 12     c:=a;
 13     a:=b;
 14     b:=c;
 15   end;
 16 
 17 procedure ac;
 18   var h,r,x,y,i:longint;
 19   begin
 20     h:=1;
 21     r:=0;
 22     for i:=1 to m do
 23       if trie[0,i]>0 then
 24       begin
 25         inc(r);
 26         q[r]:=trie[0,i];
 27       end;
 28 
 29     while h<=r do
 30     begin
 31       x:=q[h];
 32       for i:=1 to m do
 33         if trie[x,i]>0 then
 34         begin
 35           y:=trie[x,i];
 36           inc(r);
 37           q[r]:=y;
 38           j:=f[x];
 39           while (j>0) and (trie[j,i]=0) do j:=f[j];
 40           f[y]:=trie[j,i];
 41         end;
 42       inc(h);
 43     end;
 44   end;
 45 
 46 procedure gauss;
 47   var i,j,k,p,u:longint;
 48       c:double;
 49   begin
 50     u:=0;
 51     for i:=0 to t do
 52     begin
 53       p:=u;
 54       for j:=u+1 to t do
 55         if abs(a[j,i])>abs(a[p,i]) then p:=j;
 56 
 57       if (p=u) and (a[p,i]=0) then continue;
 58       if p<>u then
 59       begin
 60         for j:=0 to t+1 do
 61           swap(a[u,j],a[p,j]);
 62       end;
 63       for j:=u+1 to t do
 64         if a[j,i]<>0 then
 65         begin
 66           c:=a[j,i]/a[u,i];
 67           for k:=0 to t+1 do
 68             a[j,k]:=a[j,k]-a[u,k]*c;
 69         end;
 70       inc(u);
 71     end;
 72     for i:=t downto 0 do
 73     begin
 74       if a[i,i]=0 then continue;
 75       for j:=i+1 to t do
 76         a[i,t+1]:=a[i,t+1]-ans[j]*a[i,j];
 77       ans[i]:=a[i,t+1]/a[i,i];
 78     end;
 79   end;
 80 
 81 begin
 82   readln(n,l,m);
 83   for i:=1 to m do
 84   begin
 85     readln(x,y);
 86     d[i]:=x/y;
 87   end;
 88   for i:=1 to n do
 89   begin
 90     readln(s);
 91     j:=0;
 92     for k:=1 to l do
 93     begin
 94       x:=ord(s[k])-64;
 95       if trie[j,x]=0 then
 96       begin
 97         inc(t);
 98         trie[j,x]:=t;
 99       end;
100       j:=trie[j,x];
101     end;
102     w[i]:=j;
103     v[j]:=true;
104   end;
105   ac;
106   for i:=0 to t do
107   begin
108     a[i,i]:=-1;
109     if not v[i] then
110     begin
111       for k:=1 to m do
112       begin
113         j:=i;
114         while (j>0) and (trie[j,k]=0) do j:=f[j];
115         a[trie[j,k],i]:=a[trie[j,k],i]+d[k];
116       end;
117     end;
118   end;
119   for i:=0 to t do
120     if not v[i] then a[0,i]:=0 else a[0,i]:=1;
121   a[0,t+1]:=1;
122   gauss;
123   for i:=1 to n do
124     if (ans[w[i]]>0) and (ans[w[i]]<=1) then
125       writeln(ans[w[i]]:0:2)
126     else writeln('0.00');
127 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4472985.html