Description

题库链接

有 \(n\) 个敌方单位,初始第 \(i\) 个单位的血量为 \(m_i\) 。共 \(Q\) 次操作,分两种:

  1. 对某一个单位以 \(p\) 的概率造成 \(1\) 点伤害。
  2. 对 \(k\) 个指定的敌方单位施放技能,只能命中恰好 \(1\) 个敌方单位。命中每个存活的敌方单位的概率是相等的(也就是说已经死亡的敌方单位不会有任何影响)。求命中各敌人的概率分别是多少。该类操作不会超过 \(C\) 次。

最后要求每个敌方单位的血量的期望。

\(n \leq 200 , Q \leq 200000 , C \leq 1000 , m_i \leq 100\)

Solution

不妨记 \(pk_{i,j}\) 表示第 \(i\) 个单位还剩血量为 \(j\) 时的概率。这样是可以用 \(O(Q\times m_i)\) 来维护的。

用 \(pk\) 数组我们可以计算出第 \(i\) 个单位存活概率为 \(p_i\) 。

得到这个概率,我们可以用 \(O(Cn^3)\) 的 \(\text{dp}\) (背包)来统计答案。

另 \(f_{i,j}\) 表示前 \(i\) 个人中存活了 \(j\) 个的概率。通过改变转移顺序第一维可以搞掉。

考虑优化,注意到可以逆推,及不用算每个人的概率时剩下的人重新求一次。大致是:

假设放第 \(i\) 个人时, \(f\) 数组是:

\[x_0,x_1,x_2,x_3,\cdots\]

那么第 \(i\) 个人转移后的状态为:

\[x_0',x_1',x_2',x_3',\cdots=x_0(1-p_i),x_0p_i+x_1(1-p_i),x_1p_i+x_2(1-p_i),x_2p_i+x_3(1-p_i),\cdots\]

显然逆推回去 \(x_0=\frac{x_0'}{1-p_i}\) ,剩下的满足:

\[x_i=\frac{x_i'-x_{i-1}p_i}{1-p_i}\]

那么就可以逆背包过程了,可以优化到 \(O(Cn^2)\) 。

Code

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 200+5, M = 100+5, yzh = 998244353;
  4. int n, m[N], pk[N][M], u, v, q, op, p, id, pa[N], k, lst[N], inv[N], f[N], invpa[N];
  5. int quick_pow(int a, int b) {
  6. int ans = 1;
  7. while (b) {
  8. if (b&1) ans = 1ll*ans*a%yzh;
  9. a = 1ll*a*a%yzh, b >>= 1;
  10. }
  11. return ans;
  12. }
  13. int cal(int x) {
  14. int ans = 0;
  15. for (int i = 0; i < k; i++) (ans += 1ll*inv[i+1]*pa[x]%yzh*f[i]%yzh) %= yzh;
  16. return ans;
  17. }
  18. void work() {
  19. scanf("%d", &n);
  20. for (int i = 1; i <= n; i++) scanf("%d", &m[i]), pk[i][m[i]] = 1, pa[i] = 1;
  21. inv[0] = inv[1] = 1; for (int i = 2; i <= n; i++) inv[i] = -1ll*yzh/i*inv[yzh%i]%yzh;
  22. scanf("%d", &q);
  23. while (q--) {
  24. scanf("%d", &op);
  25. if (op == 0) {
  26. scanf("%d%d%d", &id, &u, &v); p = 1ll*u*quick_pow(v, yzh-2)%yzh;
  27. pk[id][0] = (pk[id][0]+1ll*pk[id][1]*p%yzh)%yzh;
  28. for (int i = 1; i <= m[id]; i++)
  29. pk[id][i] = (1ll*pk[id][i]*(1-p)%yzh+1ll*pk[id][i+1]*p%yzh)%yzh;
  30. pa[id] = 1-pk[id][0]; invpa[id] = quick_pow(pk[id][0], yzh-2);
  31. }else {
  32. scanf("%d", &k); f[0] = 1;
  33. for (int i = 1; i <= k; i++) scanf("%d", &lst[i]), f[i] = 0;
  34. for (int i = 2; i <= k; i++) {
  35. for (int j = i-1; j >= 1; j--)
  36. f[j] = (1ll*(1-pa[lst[i]])*f[j]%yzh+1ll*pa[lst[i]]*f[j-1]%yzh)%yzh;
  37. f[0] = 1ll*f[0]*(1-pa[lst[i]])%yzh;
  38. }
  39. printf("%d ", (cal(lst[1])+yzh)%yzh);
  40. for (int i = 2; i <= k; i++) {
  41. if ((pa[lst[i]]+yzh)%yzh != 1) {
  42. f[0] = 1ll*f[0]*invpa[lst[i]]%yzh;
  43. for (int j = 1; j < k; j++)
  44. f[j] = 1ll*(1ll*f[j]-1ll*pa[lst[i]]*f[j-1]%yzh)%yzh*invpa[lst[i]]%yzh;
  45. }else for (int i = 0; i < k; i++) f[i] = f[i+1];
  46. for (int j = k-1; j >= 1; j--)
  47. f[j] = (1ll*(1-pa[lst[i-1]])*f[j]%yzh+1ll*pa[lst[i-1]]*f[j-1]%yzh)%yzh;
  48. f[0] = 1ll*f[0]*(1-pa[lst[i-1]])%yzh;
  49. printf("%d ", (cal(lst[i])+yzh)%yzh);
  50. }
  51. puts("");
  52. }
  53. }
  54. for (int i = 1; i <= n; i++) {
  55. int ans = 0;
  56. for (int j = 1; j <= m[i]; j++) (ans += 1ll*j*pk[i][j]%yzh) %= yzh;
  57. printf("%d ", (ans+yzh)%yzh);
  58. }
  59. }
  60. int main() {work(); return 0; }

[CTSC 2018]假面的更多相关文章

  1. CTSC 2018 游记

    day0 李总提前一天放假,回家颓整理行李... 然而我... 早上:睡觉... 中午:睡觉... 晚上:睡觉去火车站... 吃了几把鸡,本来想带李总入坑,但他挥手拒绝然后被李总带进了炸金花的坑... ...

  2. WC 2018/CTSC 2018/APIO 2018 游记

    (要写CTSC的时候才想起来没写WC2018,那就粗略回顾一下吧hhhhh) WC 2018(简略版): 大概和 一个宁夏和一个天津的大哥一个宿舍hhhh,字典序分宿舍真是奇妙. WC讲课真的不是人听 ...

  3. CTSC 2018酱油记

    Day0 5.5 花了一上午的时间把codechef div2的前四题切了,又在zbq老司机的指导下把第五题切了 中午12:00 gryz电竞组从机房出发,临走的时候看到很多学长挺恋恋不舍的,毕竟可能 ...

  4. [CTSC 2018] 混合果汁

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=5343 [算法] 对于每组询问 , 首先二分答案 显然 , 最优策略为优先选择价格低的 ...

  5. Solution -「CTSC 2018」「洛谷 P4602」混合果汁

    \(\mathcal{Description}\)   Link.   \(n\) 种果汁,第 \(i\) 种美味度为 \(d_i\),每升价格 \(p_i\),一共 \(l_i\) 升.\(m\) ...

  6. APIO 2018 游记

    上接CTSC 2018 游记 day1 早上大概八九点起来洗了个澡跑到隔壁寝发现 tj 还在??? 原来昨天晚上听错名字了... 下午一起去 wfj 王府井玩,陪李总逛逛奢侈品店... 走了两三个小时 ...

  7. About me & 一些置顶的博文

    About me 一只历史上最弱的 \(\text{hnoier}\) ... 身在 \(\text{hn}\) 弱校,除了在四大名校夹缝中生存,还要受到同校 \(\text{Julao}\) 的鄙视 ...

  8. NOIWC 2019 冬眠记【游记】

    在我的blog查看:https://www.wjyyy.top/wc2019 Day -1 上火车了,but手机没电了. Day 0 中午1点左右到了广州东站.接站只有南站和机场有,于是坐了一个多小时 ...

  9. 2018 CTSC&APIO 游记

    CTSC 居然是CTSC先考,弄得我有些意外. 5.6 早上5:30乘坐高铁来到北京,差不多下午了吧,具体几点忘记了,然后来到宾馆   试机也没有去,就直接在宾馆颓废了. 5.7 考试的第一天,6:3 ...

随机推荐

  1. EnyimMemcached中用DateTime参数设置过期后赋值有问题的解决.

    环境: win10 64位.memcached 1.4.4 64位.EnyimMemcached 2.16.0(ps:2.13.0也有此问题,别的版本就没试了). EnyimMemcached git ...

  2. .NET MVC CSRF/XSRF 漏洞

    最近我跟一个漏洞还有一群阿三干起来了…… 背景: 我的客户是一个世界知名的药企,最近这个客户上台了一位阿三管理者,这个货上线第一个事儿就是要把现有的软件供应商重新洗牌一遍.由于我们的客户关系维护的非常 ...

  3. ruby,gem,rails之间的关系

    Q:ruby,gem,rails之间的关系? 简单点说:Ruby是一种脚本语言,Gem是基于Ruby的一些开发工具包,Rails也算是一组Gem,专门用来做网站的.不同的Gem可能会依赖不同的Ruby ...

  4. wpf简单进度条

    UserControl x:Class="WpfApplication1.UserControl2" xmlns="http://schemas.microsoft.co ...

  5. HttpWebRequest和WebClient的用法

    //通过web方式,从远程服务器端下载文件: public static void DownLoad(string Url, string FileName, string machinetype) ...

  6. 关于win10 链接安卓设备报错winusb.sys未经签名的解决办法

    很简单,各位,我找了一个签过名的winusb.sys替换原来的文件即可. 操作系统win10 64位专业版(更新到最新版本了) 网盘地址 安装好以后,就没有那个惊叹号咯!

  7. Neutron 架构图

    与 OpenStack 其他服务一样,Neutron 采用的是分布式架构,包括 Neutorn Server.各种 plugin/agent.database 和 message queue. Neu ...

  8. Java基础学习篇---------static

    一.static的使用 1.使用static定义的属性往往通过类名直接调用,它的属性(方法)不属于某一个的对象的.所以对象没有创建之前就可以对static的属性的调用,方法亦如此. 2.static ...

  9. centos7 安装django

    环境:centos7.4  ,python用的venv 3.6 ,django 2.1 注意点:django2.2再使用venv环境的时候会报SQList版本不足问题,升级数据库太费劲,不如重来 安装 ...

  10. ehcache 页面整体缓存和局部缓存

    页面缓存是否有必要?. 这样说吧,几乎所有的网站的首页都是访问率最高的,而首页上的数据来源又是非常广泛的,大多数来自不同的对象,而且有可能来自不同的db ,所以给首页做缓存是很必要的.那么主页的缓存策 ...