【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)
【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)
题面
题解
第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了。然而点数太多了,三方的消元没法做。
考虑如何优化点数,首先我们的所有点可以分为两种,一种是终止节点,另外一种则不是。
既然现在要某一个串出现,因此我们唯一需要考虑的是到达终止节点的情况。设\(f_i\)表示到达第\(i\)个串的终止位置,并且没有到达过其他终止节点的概率,也就是第\(i\)个串的答案。设\(f_0\)表示没有到达任何一个串终止位置的概率。
那么显然的,要到达当前位置,我们一种可行的方法就是在没有匹配上任何一个串的串后面接上当前串,那么概率就是\(f_0*\frac{1}{2^m}\),然而这个东西显然会比\(f_i\)要大,因为这个终止串再接上当前串可能包含了其他的串\(j\),而\(f_0\)表示的串没有匹配上任何一个串,意味着\(j\)的后缀是\(i\)的前缀。那么考虑所有其他串与当前串前后缀的匹配长度\(k\),我们可以列出方程:
\]
而然这样子是\(n+1\)元,\(n\)个方程,再利用\(\sum f_i=1\)补足最后一个方程即可。
好神仙啊。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define ull unsigned long long
#define MAX 320
const ull base=233;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,m;char ch[MAX];
ull h[MAX][MAX],pw[MAX];
ull geths(int x,int l,int r){return h[x][r]-h[x][l-1]*pw[r-l+1];}
double g[MAX][MAX],bin[MAX];
void Guass()
{
for(int i=0;i<=n;++i)
{
int p=i;
for(int j=i+1;j<=n;++j)if(fabs(g[j][i])>fabs(g[p][i]))p=j;
swap(g[p],g[i]);
double t=g[i][i];
for(int j=i;j<=n+1;++j)g[i][j]/=t;
for(int j=i+1;j<=n;++j)
{
double t=g[j][i];
for(int k=0;k<=n+1;++k)g[j][k]-=g[i][k]*t;
}
}
for(int i=n;i;--i)
{
g[i][n+1]/=g[i][i];
for(int j=i-1;j;--j)
g[j][n+1]-=g[i][n+1]*g[j][i];
}
}
int main()
{
n=read();m=read();pw[0]=bin[0]=1;
for(int i=1;i<=m;++i)pw[i]=pw[i-1]*base,bin[i]=bin[i-1]/2;
for(int i=1;i<=n;++i)
{
scanf("%s",ch+1);
for(int j=1;j<=m;++j)h[i][j]=h[i][j-1]*base+ch[j];
}
g[0][n+1]=1;
for(int i=1;i<=n;++i)
{
g[0][i]=1;g[i][0]=-bin[m];
for(int j=1;j<=n;++j)
for(int k=1;k<=m;++k)
if(geths(i,1,k)==geths(j,m-k+1,m))
g[i][j]+=bin[m-k];
}
Guass();
for(int i=1;i<=n;++i)printf("%.10lf\n",g[i][n+1]);
return 0;
}
【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)的更多相关文章
- [BZOJ4820][SDOI2017]硬币游戏(高斯消元+KMP)
比较神的一道题,正解比较难以理解. 首先不难得出一个(nm)^3的算法,对所有串建AC自动机,将在每个点停止的概率作为未知数做高斯消元即可. 可以证明,AC自动机上所有不是模式串终止节点的点可以看成一 ...
- [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)
[BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...
- [Sdoi2017]硬币游戏 [高斯消元 KMP]
[Sdoi2017]硬币游戏 题意:硬币序列,H T等概率出现,\(n \le 300\)个人猜了一个长为$ m \le 300$的字符串,出现即获胜游戏结束.求每个人获胜概率 考场用了[1444: ...
- BZOJ4820 Sdoi2017 硬币游戏 【概率期望】【高斯消元】【KMP】*
BZOJ4820 Sdoi2017 硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实 ...
- BZOJ4820 SDOI2017硬币游戏(概率期望+高斯消元+kmp)
容易想到的做法是建出AC自动机,高斯消元.然而自动机上节点数量是nm的. 注意到我们要求的变量只有n个,考虑将其他不用求的节点合并为一个变量.这个变量即表示随机生成一个串,其不包含任何一个模板串的概率 ...
- [bzoj4820][Sdoi2017]硬币游戏
来自FallDream的博客,未经允许,请勿转载,谢谢. 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了 ...
- 【bzoj3105】[cqoi2013]新Nim游戏 高斯消元求线性基
题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...
- BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]
以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高 ...
- BZOJ 2466 中山市选2009 树 高斯消元+暴力
题目大意:树上拉灯游戏 高斯消元解异或方程组,对于全部的自由元暴力2^n枚举状态,代入计算 这做法真是一点也不优雅... #include <cstdio> #include <cs ...
随机推荐
- Rabbitmq-direct演示
在上一节中我们创建了一个日志系统.实现将日志消息广播给所有的cusumer. 在这片教程中,我们将为日志系统添加一个功能:仅仅订阅一部分消息.比如:我们可以直接将关键的错误类型日志消息保存到日志文件中 ...
- 【LGR-047】洛谷5月月赛
这次我期待了很久的Luogu月赛崩掉了 传说中的Luogu神机就这样被卡爆了 然后我过了20min才登上Luogu的网站,30min后才看到题目 然后交T1TM的不给我测!!!然后又交了一次机子就炸了 ...
- Visual Studio 2019 Serial Keys
Visual Studio 2019 Enterprise BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional NYWVH-HT ...
- 【亲测有效】无法定位链接器!请检查 tools\link.ini 中的配置是否正确的解决方案
在进行易语言静态编译的时候,出现了如下错误: 正在进行名称连接...正在统计需要编译的子程序正在编译...正在生成主程序入口代码程序代码编译成功等待用户输入欲编译到的文件名正在进行名称连接...开始静 ...
- Wannafly挑战赛25 B.面积并
链接 [https://www.nowcoder.com/acm/contest/197/B] 分析 特殊优先考虑 首先考虑r>=l这种情况就是圆的面积了 第二就是r<=内切圆的半径,这个 ...
- week3-构造一个简单的linux系统
潘恒 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.gdb跟踪调试内核 ...
- Linux内核学习期末总结(网课)
标签(空格分隔): 20135321余佳源 余佳源(原创作品转载请注明出处) <Linux内核分析> MOOC课程http://mooc.study.163.com/course/USTC ...
- Python学习笔记 -- 第五章
模块 使用模块可以提高了代码的可维护性.其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块: ...
- 【论文笔记】Domain Adaptation via Transfer Component Analysis
论文题目:<Domain Adaptation via Transfer Component Analysis> 论文作者:Sinno Jialin Pan, Ivor W. Tsang, ...
- MySQLi面向对象实践--insert、update、delete
执行insert <?php $mysqli = new Mysqli(); $mysqli->connect("localhost","root" ...