题目链接

BZOJ5340

题解

我们能很容易维护每个人当前各种血量的概率

设\(p[u][i]\)表示\(u\)号人血量为\(i\)的概率

每次攻击的时候,讨论一下击中不击中即可转移

是\(O(Qm^2)\)的

现在考虑一下结界

如果我们设\(f[u][i]\)表示除了\(u\)还存活\(i\)个人的概率

那么

\[ans[u] = (1 - p[u][0]) \sum\limits_{i = 0}^{k - 1} \frac{f[u][i]}{i + 1}
\]

所以我们只需计算\(f[u][i]\)

\(f[u][i]\)同样可以通过枚举剩余每个人存活与否进行转移,是\(O(n^3)\)的,复杂度过高

我们考虑计算\(g[i]\)表示剩余\(i\)人的概率

枚举\(u\)

\[g'[i] = g[i]p[u][0] + g[i - 1](1 - p[u][0])
\]

即可\(O(n^2)\)计算\(g[i]\)

如果我们拿\(f[u][i]\)来计算\(g[i]\)的话

\[g[i] = f[u][i]p[u][0] + f[u][i - 1](1 - p[u][0])
\]

那么

\[f[u][i] = \frac{g[i] - f[u][i - 1](1 - p[u][0])}{p[u][0]}
\]

也可以\(O(n^2)\)递推

这样我们就做完了

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #include<map>
  7. #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
  8. #define REP(i,n) for (int i = 1; i <= (n); i++)
  9. #define mp(a,b) make_pair<int,int>(a,b)
  10. #define cls(s) memset(s,0,sizeof(s))
  11. #define cp pair<int,int>
  12. #define LL long long int
  13. using namespace std;
  14. const int maxn = 205,maxm = 105,INF = 1000000000,P = 998244353;
  15. inline int read(){
  16. int out = 0,flag = 1; char c = getchar();
  17. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  18. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  19. return out * flag;
  20. }
  21. LL p[maxn][maxm],f[maxn][maxn],g[maxn][maxn],n,m[maxn],id[maxn];
  22. LL INV[maxn];
  23. inline LL qpow(LL a,LL b){
  24. LL ans = 1;
  25. for (; b; b >>= 1,a = 1ll * a * a % P)
  26. if (b & 1) ans = 1ll * ans * a % P;
  27. return ans;
  28. }
  29. inline LL inv(int x){
  30. if (x <= n) return INV[x];
  31. return qpow(x,P - 2);
  32. }
  33. int main(){
  34. n = read();
  35. REP(i,n) m[i] = read(),p[i][m[i]] = 1;
  36. INV[0] = 1; INV[1] = 1;
  37. for (int i = 2; i <= n; i++) INV[i] = 1ll * (P - P / i) * INV[P % i] % P;
  38. LL Q = read(),opt,u,v,pp,x,k;
  39. while (Q--){
  40. opt = read();
  41. if (!opt){
  42. x = read(); u = read(); v = read(); pp = u * inv(v) % P;
  43. p[x][0] = (p[x][0] + pp * p[x][1] % P) % P;
  44. for (int i = 1; i <= m[x]; i++)
  45. p[x][i] = ((p[x][i] * (1 - pp) % P + p[x][i + 1] * pp % P) % P + P) % P;
  46. }
  47. else {
  48. k = read();
  49. cls(g); g[0][0] = 1;
  50. for (int i = 1; i <= k; i++){
  51. u = id[i] = read();
  52. g[i][0] = g[i - 1][0] * p[u][0] % P;
  53. for (int j = 1; j <= i; j++){
  54. g[i][j] = ((g[i - 1][j] * p[u][0] % P + g[i - 1][j - 1] * (1 - p[u][0]) % P) % P + P) % P;
  55. }
  56. }
  57. for (int i = 1; i <= k; i++){
  58. u = id[i];
  59. LL ans = 0,Inv = inv(p[u][0]);
  60. if (!p[u][0]){
  61. for (int j = 0; j < k; j++)
  62. f[u][j] = g[k][j + 1];
  63. }
  64. else {
  65. f[u][0] = 1ll * g[k][0] * Inv % P;
  66. for (int j = 1; j < k; j++){
  67. f[u][j] = (1ll * (g[k][j] - 1ll * f[u][j - 1] * (1 - p[u][0]) % P) % P * Inv % P + P) % P;
  68. }
  69. }
  70. for (int j = 0; j < k; j++){
  71. ans = (ans + 1ll * f[u][j] * inv(j + 1) % P) % P;
  72. }
  73. ans = (1ll * ans * (1ll - p[u][0]) % P + P) % P;
  74. printf("%lld",ans);
  75. if (i < k) putchar(' ');
  76. else puts("");
  77. }
  78. }
  79. }
  80. for (int i = 1; i <= n; i++){
  81. LL ans = 0;
  82. for (int j = 1; j <= m[i]; j++)
  83. ans = (ans + 1ll * j * p[i][j] % P) % P;
  84. printf("%lld",ans);
  85. if (i < n) putchar(' ');
  86. else puts("");
  87. }
  88. return 0;
  89. }

BZOJ5340 [Ctsc2018]假面 【概率dp】的更多相关文章

  1. [CTSC2018]假面(概率DP)

    考场上以为CTSC的概率期望题都不可做,连暴力都没写直接爆零. 结果出来发现全场70以上,大部分AC,少于70的好像极少,感觉血亏. 设a[i][j]表示到当前为止第i个人的血量为j的概率(注意特判血 ...

  2. BZOJ5340: [Ctsc2018]假面

    BZOJ5340: [Ctsc2018]假面 https://lydsy.com/JudgeOnline/problem.php?id=5340 分析: 背包,只需要求\(g_{i,j}\)表示强制活 ...

  3. BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】

    LINK 思路 首先考虑减血,直接一个dp做过去,这个部分分不难拿 然后是\(op=1\)的部分 首先因为要知道每个人被打的概率,所以需要算出这个人活着的时候有多少个人活着时概率是什么 那么用\(g_ ...

  4. [CTSC2018] 假面 | 期望 DP

    题目链接 LOJ 2552 Luogu P4564 考场上这道题我先是写了个70分暴力,然后发现似乎可以NTT,然鹅问题是--我没学过NTT,遂脑补之,脑补出来了,下午出成绩一看,卡成暴力分(70)- ...

  5. Codeforces 28C [概率DP]

    /* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队 ...

  6. HDU 4405 Aeroplane chess (概率DP)

    题意:你从0开始,要跳到 n 这个位置,如果当前位置是一个飞行点,那么可以跳过去,要不然就只能掷骰子,问你要掷的次数数学期望,到达或者超过n. 析:概率DP,dp[i] 表示从 i  这个位置到达 n ...

  7. POJ 2096 Collecting Bugs (概率DP)

    题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...

  8. POJ 2151 Check the difficulty of problems (概率DP)

    题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...

  9. 概率DP light oj 1030

    t组数据 n块黄金 到这里就捡起来 出发点1 到n结束  点+位置>n 重掷一次 dp[i] 代表到这里的概率 dp[i]=(dp[i-1]+dp[i-2]... )/6  如果满6个的话 否则 ...

随机推荐

  1. Angular简单总结

    AngularJS AngularJS四大特征 MVC模式 双向绑定 依赖注入 模块化设计 AngularJS 表达式 AngularJS 表达式写在双大括号内{{expression }},可以包含 ...

  2. spark-day1

    #!/usr/bin/python # -*- coding: utf_8 -*- from pyspark import SparkConf, SparkContext import os, tim ...

  3. node获取URL数据

    req.method  -->GET req.hostname  -->127.0.0.1 req.originalUrl  -->/test/test/test?name=wang ...

  4. C# Winform 实现屏蔽键盘的win和alt+F4的实现代码

    最近在做一个恶搞程序,就是打开后,程序获得桌面的截图然后,然后全屏显示在屏幕上,用户此时则不能进行任何操作. 此时希望用户不能通过键盘alt+F4来结束程序及通过Win的组合键对窗口进行操作.我在网上 ...

  5. 高德API+Python解决租房问题(.NET版)

    源码地址:https://github.com/liguobao/58HouseSearch 在线地址:58公寓高德搜房(全国版):http://codelover.link:8080/ 周末闲着无事 ...

  6. OrCAD设置原理图页面大小

    1. 右键要修改的原理图文件 2. 选择适合的尺寸

  7. Can’t delete list item in Sharepoint2013

         Today,I have meet a very strange error.When I attempt to delete a item from a list,I recieve an ...

  8. 【数据库】 SQLite 语法

    [数据库] SQLite 语法 一 . 创建数据库 1. 只需创建数据库,只需创建文件,操作时将连接字符串指向该文件即可 2. 连接字符串 : data source = FilePath; 不能加密 ...

  9. 「题目代码」P1007~P1012(Java)

    1007 C基础-计负均正 import java.util.*; import java.io.*; public class Main { public static void main(Stri ...

  10. CCF-NOIP-2018 提高组(复赛) 模拟试题(七)

    T1 Adjoin [问题描述] 定义一种合法的\(0-1\)串:串中任何一个数字都与\(1\)相邻.例如长度为$ 3 的 0-1 $串中,\(101\)是非法的,因为两边的\(1\)没有相邻的\(1 ...