\(\mathscr{Description}\)

  Link.

  给定 \(n\) 个长度为 \(m\) 且两两不同的字符串 \(S_{1..n}\), 字符集 \(|\Sigma|=2\). 各位置独立在 \(\Sigma\) 中均匀随机, 生成一个足够长的字符串 \(T\), 对于每个 \(S_i\), 求 \(S_i\) 在 \(T\) 中第一次出现位置最靠前的概率.

  \(n,m\le300\).

\(\mathscr{Solution}\)

  感觉一直知道 PGF 但基本没有上手用过 qwq.

  比较套路啦, 令 \(F_i(x)\) 表示 \(S_i\) 出现位置最靠前时, 其概率关于 \(|T|\) 的 PGF; \(G(x)\) 表示没有任何 \(S\) 出现时, 其概率关于 \(|T|\) 的 PGF. 我们的目标是求所有 \(F_i(1)\).

  "\(T_i\) 被放出来的概率" = "\(|T|=i-1\) 时没有结束的概率":

\[G(x)+\sum_iF_i(x)=1+xG(x).
\]

  "从一个未结束状态向后再恰好延伸出一个 \(S_i\) 的概率" = "在放的过程中所有戛然而止 (某个 \(S_j\) 出现了) 的时候再向后强行补满未出现字符的概率":

\[2^{-m}x^mG(x)=\sum_{j=1}^n\sum_{k=1}^m[S_i[:k]=S_j[m-k+1:]]2^{k-m}x^{m-k}F_j(x).
\]

  一起令 \(x=1\):

\[\begin{cases}
G(1)+\sum_iF_i(1)=1+G(1),\\
2^{-m}G(1)=\sum_j\sum_k[S_i[:k]=S_j[m-k+1:]]2^{k-m}F_j(1)&\forall i.
\end{cases}
\]

直接对总共 \(n+1\) 个变量消元即可. 复杂度 \(\mathcal O(n^2(n+m))\).

\(\mathscr{Code}\)

/*+Rainybunny+*/

#include <bits/stdc++.h>

#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i) typedef unsigned long long ULL; const int MAXN = 300;
const ULL BASE = 127;
int n, m;
ULL hpw[MAXN + 5], hsh[MAXN + 5][MAXN + 5];
double mat[MAXN + 5][MAXN + 5], pwr[MAXN + 5], ans[MAXN + 5]; inline void init() {
hpw[0] = 1;
rep (i, 1, m) hpw[i] = hpw[i - 1] * BASE;
pwr[0] = 1;
rep (i, 1, m) pwr[i] = 0.5 * pwr[i - 1];
} inline ULL calc(const int i, const int l, const int r) {
return hsh[i][r] - hpw[r - l + 1] * hsh[i][l - 1];
} inline void gauss() {
rep (i, 0, n) {
int p = i;
rep (j, i + 1, n) if (fabs(mat[p][i]) < fabs(mat[j][i])) p = j;
if (i != p) std::swap(mat[p], mat[i]);
rep (j, i + 1, n) {
double t = mat[j][i] / mat[i][i];
rep (k, i, n + 1) mat[j][k] -= t * mat[i][k];
}
}
per (i, n, 0) {
ans[i] = mat[i][n + 1] / mat[i][i];
rep (j, 0, i - 1) mat[j][n + 1] -= ans[i] * mat[j][i];
}
} int main() {
scanf("%d %d", &n, &m), init();
rep (i, 1, n) {
static char str[MAXN + 5];
scanf("%s", str + 1);
rep (j, 1, m) hsh[i][j] = hsh[i][j - 1] * BASE + str[j];
} rep (i, 1, n) {
mat[i][0] = -pwr[m];
rep (j, 1, n) {
rep (k, 1, m) if (calc(i, 1, k) == calc(j, m - k + 1, m)) {
// printf("%d %d %d\n", i, j, k);
mat[i][j] += pwr[m - k];
}
}
}
rep (i, 1, n + 1) mat[0][i] = 1.; gauss();
rep (i, 1, n) printf("%.12f\n", ans[i]);
return 0;
}

Solution -「SDOI 2017」「洛谷 P3706」硬币游戏的更多相关文章

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

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

  2. 洛谷 3706 [SDOI2017]硬币游戏——思路

    题目:https://www.luogu.org/problemnew/show/P3706 题解:https://blog.csdn.net/gjghfd/article/details/80355 ...

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

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

  4. 「区间DP」「洛谷P1043」数字游戏

    「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...

  5. [CodePlus 2017 11月赛&洛谷P4058]木材 题解(二分答案)

    [CodePlus 2017 11月赛&洛谷P4058]木材 Description 有 n棵树,初始时每棵树的高度为 Hi ,第 i棵树每月都会长高 Ai.现在有个木料长度总量为 S的订单, ...

  6. 洛谷P1118 数字三角形游戏

    洛谷1118 数字三角形游戏 题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直 ...

  7. 洛谷P1274-魔术数字游戏

    Problem 洛谷P1274-魔术数字游戏 Accept: 118    Submit: 243Time Limit: 1000 mSec    Memory Limit : 128MB Probl ...

  8. 洛谷P1288 取数游戏II(博弈)

    洛谷P1288 取数游戏II 先手必胜的条件需要满足如下中至少 \(1\) 条: 从初始位置向左走到第一个 \(0\) 的位置,经过边的数目为偶数(包含 \(0\) 这条边). 从初始位置向右走到第一 ...

  9. Solution -「JSOI 2019」「洛谷 P5334」节日庆典

    \(\mathscr{Description}\)   Link.   给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的).   \(|S|\le3\time ...

  10. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

随机推荐

  1. Win11安装基于WSL2的Ubuntu

    1. 概述 趁着还没有完全忘记,详细记录一下在Win11下安装基于WSL2的Ubuntu的详细过程.不得不说WLS2现在被微软开发的比较强大了,还是很值得安装和使用的,笔者就通过WLS2安装的Ubun ...

  2. 关于在有动态的Scroll Bar情况下页面内容的对齐问题

    关于在有动态的Scroll Bar情况下页面内容的对齐问题 问题场景 一个标题行 + 一些内容行 要求在内容行超过指定行数时 将多出的行隐藏,并展示Scroll Bar的来提示用户可以下划查看更多内容 ...

  3. 鸿蒙Banner图一多适配不同屏幕

    认识一多 随着终端设备形态日益多样化,分布式技术逐渐打破单一硬件边界,一个应用或服务,可以在不同的硬件设备之间随意调用.互助共享,让用户享受无缝的全场景体验.而作为应用开发者,广泛的设备类型也能为应用 ...

  4. OpenAI使用AI编程给出了数数问题的解决方案 —— 如何解决ChatGPT不会数数的问题

    总所周知的一个问题,那就是ChatGPT不会数数,不过今天突然发现OpenAI给出了一个神奇的解决方法,那就是AI编程. 问题案例如下: The text provided will be analy ...

  5. 拿去面试!一个基于 DDD 的高性能短链系统

    众所周知,商城.RPC.秒杀.论坛.外卖.点评等项目早早就烂大街了,翻开同学的简历一看 10 个里面有 9 个是这些,翻遍全网再很难找到一个既有含金量又能看得懂的项目,针对此,我研发了这样一个可以快速 ...

  6. Docker制作私有镜像仓库

    构建私有仓库 启动Docker Registry,使用Docker官方提供的Registry镜像就可以搭建本地私有镜像仓库,具体指令如下. docker run -d -p 5000:5000 --r ...

  7. 基于surging的木舟平台如何构建起微服务

    一.概述 木舟平台分为微服务平台和物联网平台, 上面几篇都是介绍如何通过网络组件接入设备,那么此篇文章就细致介绍下在木舟平台下如何构建微服务. 木舟 (Kayak) 是什么? 木舟(Kayak)是基于 ...

  8. Mysql篇-语句执行计划详解(explain)

    概述 使用 explain 输出 SELECT 语句执行的详细信息,包括以下信息: 表的加载顺序 sql 的查询类型 可能用到哪些索引,实际上用到哪些索引 读取的行数 Explain 执行计划包含字段 ...

  9. 鸿蒙开发Hvigor插件动态生成代码

    Hvigor允许开发者实现自己的插件,开发者可以定义自己的构建逻辑,并与他人共享.Hvigor主要提供了两种方式来实现插件:基于hvigorfile脚本开发插件.基于typescript项目开发.下面 ...

  10. python get请求传array数组

    前言 使用传统的http发get请求时,如果传参为array数组,参数名称为a时,可以这样传值a=1&a=2&a=3,但是当只有一个时,这种方式就不合理了. get请求还有另外一种方式 ...