[ARC174C] Catastrophic Roulette 题解

· · 题解

传送门:Luogu / AtCoder。

首次参赛 ARC,1100 分,749 名(菜就多练,越练越菜)。C 题是 ABCD 四题里我唯一不会的,ABD 共计 1h 全 AC,C 题 10min 无思路,就被赶进房间、被逼迫睡觉了,wuwu……

emem,咱们切入正题。

求期望值?DP,启动!显然,数据范围 1\le n\le 10^6 只允许我们使用 O(n) DP。你根本不知道这个游戏要玩几轮(如果双方“默契”地一直抽 1,轮数就 =\infty),所以不能把轮数作为状态维度。

显然,抽到过的卡牌数量相同,则期望值相同,否则不同,具体抽到哪些卡牌无需理会。尝试用“抽到过的卡牌数量”作 DP 维度。

用 f1_i 表示“抽到过的卡牌数量变成 i 的那刻,先手的罚款期望值”。

用 f2_i 表示“抽到过的卡牌数量变成 i 的那刻,后手的罚款期望值”。

边界:f1_1=f2_1=0。

转移方程:f1_{i+1}=f1_i+A。

那怎么求 $A$ 呢? 显然,$A$ 是一条级数式,而常数项相同的级数式较易求和。设 $h1=$ 抽到过的卡牌数量变成 $i$ 后轮到先手的概率,$h2=$ 抽到过的卡牌数量变成 $i$ 后轮到后手的概率,则有: $A=(h1\times \frac{i}{n}+h1\times\frac{i}{n}\times\frac{i}{n}\times\frac{i}{n}+...)+(h2\times\frac{i}{n}\times\frac{i}{n}+h2\times\frac{i}{n}\times\frac{i}{n}\times \frac{i}{n}\times\frac{i}{n}) \>\>\>\>=h1\times\frac{i}{n}\times(1+(\frac{i}{n})^2+(\frac{i}{n})^4+...)+h2\times(\frac{i}{n})^2\times(1+(\frac{i}{n})^2+(\frac{i}{n})^4+...)

设 p=\frac{i}{n},则 1+(\frac{i}{n})^2+(\frac{i}{n})^4+...=\frac{1}{1-p^2}。

代入原式,$f1_{i+1}=f1_i+h1\times\frac{p}{1-p^2}+h2\times\frac{p^2}{1-p^2}$。 同理,$f2_{i+1}=f2_i+h2\times\frac{p}{1-p^2}+h1\times\frac{p^2}{1-p^2}$。 问题:怎么求 $h1$,$h2$ 呢? 简单,DP,启动! 用 $h1_i$ 表示“**抽到过的卡牌数量变成 $i$ 后轮到先手的概率**”。 用 $h2_i$ 表示“**抽到过的卡牌数量变成 $i$ 后轮到后手的概率**”。 边界:$h1_1=0,h2_1=1$。 转移方程推导: $h1_{i+1}=(h1_i\times p\times (1-p)+h1_i\times p\times p\times p\times (1-p)+...)+(h2_i\times (1-p)+h2_i\times p\times p\times (1-p)+...) \>\>\>\>\>\>\>\>\>\>\>=h1\times p\times (1-p)\times \frac{1}{1-p^2}+h2\times (1-p)\times \frac{1}{1-p^2} 同理,$h2_{i+1}=\frac{1}{1+p}\times (h2\times p+h1)$。 最终答案为 $(f1_n,f2_n)$。 代码: ```cpp #include<bits/stdc++.h> using namespace std; const int N=1000005; const int mod=998244353; typedef long long ll; int n; int h1[N],h2[N],f1[N],f2[N]; int qpow(int a,int b){ int res=1; while(b){ if(b&1) res=(ll)res*a%mod; a=(ll)a*a%mod; b>>=1; } return res; } int inv(int x){ return qpow(x,mod-2); } int main(){ scanf("%d",&n); h2[1]=1; for(int i=1;i<n;i++){ int p=(ll)i*inv(n)%mod; h1[i+1]=(h2[i]+(ll)h1[i]*p)%mod*inv(1+p)%mod; h2[i+1]=(h1[i]+(ll)h2[i]*p)%mod*inv(1+p)%mod; f1[i+1]=(f1[i]+(h1[i]+(ll)h2[i]*p)%mod*p%mod*inv((1-(ll)p*p%mod+mod)%mod)%mod)%mod; f2[i+1]=(f2[i]+(h2[i]+(ll)h1[i]*p)%mod*p%mod*inv((1-(ll)p*p%mod+mod)%mod)%mod)%mod; } printf("%d %d",f1[n],f2[n]); return 0; } ```