表示高斯消元总写错。。。
注意,概率和期望高斯消元,我们消的时候,取一个fabs最大的就好,别用eps判了,re惨了。。
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=305;
int n,m,pos[N];
int head[N*N],tot,to[N*N],pre[N*N];
void addedge(int u,int v) {to[++tot]=v;pre[tot]=head[u];head[u]=tot;}
char s[N];int ch[N*N][2],cnt,dep[N*N],fail[N*N];
inline int idx(char ch) {return ch=='T'? 0:1;}
void get_fail()
{
queue<int> q;
if (ch[0][0]) q.push(ch[0][0]);
if (ch[0][1]) q.push(ch[0][1]);
while (!q.empty())
{
int u=q.front();q.pop();
for (int i=0;i<=1;i++)
if (ch[u][i]==0) ch[u][i]=ch[fail[u]][i];
else fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
}
}
double a[N][N],bin[N];
void jump(int id)
{
a[id][n+1]=-bin[m];
int x=pos[id];
while (x)
{
for (int i=head[x];i;i=pre[i]) a[to[i]][id]+=bin[m-dep[x]];
x=fail[x];
}
}
void gauss(int n)
{
for (int i=1;i<=n;i++)
{
int j=i;
for (int k=i+1;k<=n;k++) if (fabs(a[k][i])>fabs(a[i][i])) j=k;
if (i!=j) swap(a[i],a[j]);
double tmp=a[i][i];
for (j=i;j<=n+1;j++) a[i][j]/=tmp;
for (j=1;j<=n;j++) if (j!=i)
{
tmp=a[j][i];
for (int k=1;k<=n+1;k++) a[j][k]-=a[i][k]*tmp;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
bin[0]=1;for (int i=1;i<=m;i++) bin[i]=bin[i-1]*0.5;
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
int u=0,id;
for (int j=1;j<=m;j++)
{
id=idx(s[j]);
if (ch[u][id]==0) ch[u][id]=++cnt;
u=ch[u][id];dep[u]=j;addedge(u,i);
}
pos[i]=u;
}
get_fail();
for (int i=1;i<=n;i++) jump(i);
for (int i=1;i<=n;i++) a[n+1][i]=1.0;
a[n+1][n+2]=1.0;
gauss(n+1);
for (int i=1;i<=n;i++) printf("%.10lf\n",a[i][n+2]);
return 0;
}