正题

题目链接:https://www.luogu.com.cn/problem/P3706


题目大意

给出 \(n\) 个长度为 \(m\) 的 \(H/T\) 串。

开始一个空序列,每次随机在后面加一个 \(H/T\) ,求每个串第一次出现的概率。

\(1\leq n,m\leq 300\)


解题思路

数据范围显然不能在AC自动机上高斯消元,所以得考虑别的方法。

考虑一个很妙的做法,设一个状态\(N\)表示目前还没有匹配完成的串,然后考虑串\(A=HHT\)和串\(B=THH\),那么在\(N\)后面直接插入一个\(A\)的概率就是\(p(N+A)=p(N)\times 2^{-m}\)

但是考虑到有可能\(N\)先拼出了\(B\)然后再拼出\(A\),此时考虑\(B\)的后缀对应\(A\)前缀的有\(H,HH\)。那么就有

\[p(N)\times 2^{-m}=p(N+A)=p(A)+p(B)\times 2^{-2}+p(B)\times 2^{-1}
\]

这样不难发现对于别的串如果它的一些后缀是这个串的前缀那么就会产生一些概率,用字符串\(hash\)匹配即可。

然后会发现还是少了一个方程,最后一个就是所有串的概率和为\(1\)就好了。

这样就有\(n+1\)个方程了。

时间复杂度:\(O(n^2m+n^3)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ull unsigned long long
using namespace std;
const int N=310;
const ull g=131;
int n,m;
double a[N][N],b[N],pw[N];
ull h[N][N],p[N];char s[N];
ull geth(int x,int l,int r)
{return h[x][r]-h[x][l-1]*p[r-l+1];}
void Gauss(int n){
for(int i=1;i<=n;i++){
int z=i;
for(int j=i+1;j<=n;j++)
if(a[j][i]>a[z][i])z=i;
swap(a[i],a[z]);
double x=a[i][i];b[i]/=x;
for(int j=i;j<=n;j++)a[i][j]/=x;
for(int j=i+1;j<=n;j++){
double rate=-a[j][i];
for(int k=i;k<=n;k++)
a[j][k]+=rate*a[i][k];
b[j]+=rate*b[i];
}
}
for(int i=n;i>=1;i--){
for(int j=1;j<i;j++){
b[j]-=a[j][i]*b[i];
a[j][i]=0;
}
}
return;
}
int main()
{
scanf("%d%d",&n,&m);p[0]=1;pw[0]=1;
for(int i=1;i<=m;i++)
pw[i]=pw[i-1]*0.5,p[i]=p[i-1]*g;
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=m;j++)
h[i][j]=h[i][j-1]*g+s[j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=m;k++)
if(geth(i,1,k)==geth(j,m-k+1,m))
a[i][j]+=pw[m-k];
for(int i=1;i<=n;i++)
a[i][n+1]=-pw[m],a[n+1][i]=1;
b[n+1]=1;Gauss(n+1);
for(int i=1;i<=n;i++)
printf("%.12lf\n",b[i]);
return 0;
}

P3706-[SDOI2017]硬币游戏【高斯消元,字符串hash】的更多相关文章

  1. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

  2. [Sdoi2017]硬币游戏 [高斯消元 KMP]

    [Sdoi2017]硬币游戏 题意:硬币序列,H T等概率出现,\(n \le 300\)个人猜了一个长为$ m \le 300$的字符串,出现即获胜游戏结束.求每个人获胜概率 考场用了[1444: ...

  3. [BZOJ4820][SDOI2017]硬币游戏(高斯消元+KMP)

    比较神的一道题,正解比较难以理解. 首先不难得出一个(nm)^3的算法,对所有串建AC自动机,将在每个点停止的概率作为未知数做高斯消元即可. 可以证明,AC自动机上所有不是模式串终止节点的点可以看成一 ...

  4. 洛咕 P3706 [SDOI2017]硬币游戏

    假设f[i]是第i个同学胜利的概率,也就是随机序列第一个匹配到s[i]的概率 假设前面有一个字符串\(S\),(假设无限长但没有匹配),现在往后面要加上第i个串\(s[i]\),这个的概率设为\(P_ ...

  5. 【bzoj3105】[cqoi2013]新Nim游戏 高斯消元求线性基

    题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...

  6. BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]

    以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高 ...

  7. 洛谷P3706 [SDOI2017]硬币游戏(概率生成函数+高斯消元)

    题面 传送门 题解 不知道概率生成函数是什么的可以看看这篇文章,题解也在里面了 //minamoto #include<bits/stdc++.h> #define R register ...

  8. BZOJ 2466 中山市选2009 树 高斯消元+暴力

    题目大意:树上拉灯游戏 高斯消元解异或方程组,对于全部的自由元暴力2^n枚举状态,代入计算 这做法真是一点也不优雅... #include <cstdio> #include <cs ...

  9. BZOJ:4820: [Sdoi2017]硬币游戏&&BZOJ:1444: [Jsoi2009]有趣的游戏(高斯消元求概率)

    1444: [Jsoi2009]有趣的游戏 4820: [Sdoi2017]硬币游戏 这两道题都是关于不断随机生成字符后求出现给定字符串的概率的问题. 第一题数据范围较小,将串建成AC自动机以后,以A ...

随机推荐

  1. windows上python3安装

    下载python 下载地址 https://www.python.org/downloads/windows/ 安装python 1.添加python到环境变量 2.自定义安装 3.下一步 4.选择安 ...

  2. TCP三次握手中SYN,ACK,Seq含义

    TCP(Transmission Control Protocol)传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标示 ...

  3. ES6对象扩展——扩展运算符

    1.复制对象:使用扩展运算符复制对象时是浅拷贝 //复制对象:使用扩展运算符复制对象时是浅拷贝 const obj1 = { a:1, b:2, d:{ aa:1, bb:2 } } const ob ...

  4. 关于通用Mapper new Example使用记录

    关于通用MapperExample使用记录 环境准备 需要集成 mybatis 的 generator 插件,方便自动生成 实体类和 mapper 类,还可以生成xml,不过一般我们都不用 xml b ...

  5. @RequestParam注解的详细介绍

    @RequestParam (org.springframework.web.bind.annotation.RequestParam)用于将指定的请求参数赋值给方法中的形参. 有三个属性: (1)v ...

  6. VS2017 提示找不到某个.dll库,或某个dll库丢失,原因

    可能因为那个dll的确不存在 可能因为需要在环境变量->系统环境变量->添加该dll所在目录

  7. 分享几个下载豆瓣资源的chrome插件

    最近chrome终于以4.69%的市场占有率击败firefox成为中国第二大浏览器.(第一当然是争霸宇宙的IE了) 虽然chrome官方应用程序商店有不少豆瓣的辅助插件,但大多没什么用.属于蛋疼插件. ...

  8. k8s笔记0528-基于KUBERNETES构建企业容器云手动部署集群记录-4

    部署kubelet 1.二进制包准备 将软件包从linux-node1复制到linux-node2中去. [root@linux-node1 ~]# cd /usr/local/src/kuberne ...

  9. Cookie在哪里看

    更多java学习请进: https://zhangjzm.gitee.io/self_study

  10. 超实用的idea技巧,windows技巧,用于节省时间!

    进去https://zhangjzm.gitee.io/self_study 找平常积累,或者其它的