首页 > 其他分享 >Solution -「SDOI 2017」「洛谷 P3706」硬币游戏

Solution -「SDOI 2017」「洛谷 P3706」硬币游戏

时间:2022-10-07 22:58:03浏览次数:92  
标签:洛谷 mat int rep P3706 MAXN pwr sum SDOI

\(\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;
}

标签:洛谷,mat,int,rep,P3706,MAXN,pwr,sum,SDOI
From: https://www.cnblogs.com/rainybunny/p/16767406.html

相关文章

  • P5730 【深基5.例10】显示屏 洛谷
    #include<stdio.h>intmain(){charstr1[30]="XXX..XXXXXXXX.XXXXXXXXXXXXXXXX";charstr2[30]="X.X..X..X..XX.XX..X....XX.XX.X";charstr3[30]="X.......
  • 网络流24题 -洛谷 P2762 太空飞行计划问题
    P2762太空飞行计划问题题意给你n个实验m个仪器(原题中n和m反了一下)第i个实验会给一个赞助费\(c[i]\)每个实验都有相应的实验仪器买第m个实验器材要\(c_2[i]\)的钱问......
  • 洛谷——P1071 [NOIP2009 提高组] 潜伏者
    本次博客,我将记录洛谷P1071潜伏者[NOIP2009提高组]潜伏者理解题意:对于failed的情况,有以下三种:1.扫描完毕后发现某个字母没有对应的翻译2.扫描过程中发现自相矛盾,这......
  • P2149 [SDOI2009] Elaxia的路线 题解
    首先考虑分别求出在两个人最短路上的边,这个就是用\(s\)跑一遍最短路,\(t\)跑一遍最短路,然后枚举边\((u,v)\),如果满足\((s\tou)+(u\tov)+(t\tov)=(s\tot)\)那么......
  • *洛谷 P1018 [NOIP2000 提高组] 乘积最大(dfs+高精度)
    说在前头此篇题解是记录自己的暴力写法,并不能100分满分通过洛谷测试数据(只有60)纯纯记录写法而写https://www.luogu.com.cn/problem/P1018我还说这么简单呢这题,想太......
  • [题解]洛谷 P4700
    经典题没做出来,是不是该死?是不是该死?首先缩点什么的都是套路性的,然后发现一个事,你要是缩完点直接做,就相当于有向无玕图上标记一些点,求另一些点能到达多少个标记点,这个似乎......
  • 洛谷1351 -- 联合权值
      遍历一遍树,在遍历的同时,传入节点u的父亲和祖父,计算答案#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;......
  • 洛谷 P1340 兽径管理
    题干 悲怆历程(主要还是因为自己作死)啊这个题,一眼就是克鲁斯卡尔最小生成树简介题意:$n$个点,添加$W$次边,每次添加边都询问最小生成树其中1<=n<=200,1<=......
  • 洛谷 P1827 [USACO3.4] 美国血统 American Heritage(后序遍历)
    https://www.luogu.com.cn/problem/P1827题目大意:已知前序中序遍历求后序遍历。输入#1ABEDFCHGCBADEFGH输出#1AEFDBHGC#include<bits/stdc++.h>usingn......
  • 洛谷 P7931
    以下标为横坐标,值为纵坐标,建立坐标系。然后会发现每个点的后继在其右上方。按照每个点LIS大小来分层,以样例\(3\)为例:注意到同层之间一定满足\(x\)递增\(y\)递......