[cf1349D]Slime and Biscuits

枚举最终的获得所有饼干的人$i$(以下简称"获胜者"),对于$i$获胜的情况,令其贡献为游戏轮数,否则其贡献为0,记$F_{i}$为期望贡献(即所有情况概率*贡献之和),答案即为$\sum_{i=1}^{n}F_{i}$

但此时的$F_{i}$比较复杂,其不仅取决于第$i$个人的饼干数量,还取决于别人的饼干数量,因为如果有一个人先获得了所有饼干,虽然游戏还可以继续,但$i$并不是获胜者

虽然如此,我们还是先算出在不管其他人的情况下(即另一个人获得所有饼干游戏并不结束),有$i$个饼干的人获胜的期望轮数$G_{i}$,则有$G_{a_{i}}=\sum_{j=1}^{n}F_{j}+(1-p_{i})G_{0}$

关于这个式子,$\sum_{j=1}^{n}g_{j}$即为游戏的期望轮数,那么这么多轮后,有$1-p_{i}$的概率并不是$i$获胜,而对于$G_{a_{i}}$来说此时还没有结束,而$i$必然只有0张牌,即还需要$G_{0}$步

将所有$i$累加,即$\sum_{i=1}^{n}G_{a_{i}}=n\sum_{j=1}^{n}F_{j}+(n-1)G_{0}$

由此,可以得到$\sum_{j=1}^{n}F_{j}=\frac{\sum_{i=1}^{n}G_{a_{i}}-(n-1)G_{0}}{n}$,下面考虑如何求出$G_{i}$,显然有转移
$$
\begin{cases}G_{S}=0\\G_{0}=\frac{n-2}{n-1}G_{0}+\frac{1}{n-1}G_{1}+1\\G_{i}=\frac{i}{S}G_{i-1}+\frac{S-i}{S}(\frac{1}{n-1}G_{i+1}+\frac{n-2}{n-1}G_{i})+1&(1\le i<S)\end{cases}
$$
将其变形,即有
$$
\begin{cases}G_{S}=0\\G_{0}=G_{1}+(n-1)\\\frac{S-i}{n-1}(G_{i}-G_{i+1})=i(G_{i-1}-G_{i})+S&(1\le i<S)\end{cases}
$$
记$g_{i}=G_{i}-G_{i+1}$,代入即
$$
\begin{cases}g_{0}=n-1\\g_{i}=\frac{n-1}{S-i}(i\cdot g_{i-1}+S)&(1\le i<S)\end{cases}
$$
由此即可算出$g_{i}$,再通过$G_{i}=\sum_{j=i}^{S-1}g_{j}$也即可算出$G_{i}$,进而也即可求出答案

总复杂度为$o(S)$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 300005
 4 #define mod 998244353
 5 #define ll long long
 6 int n,m,ans,inv[N],a[N],g[N],G[N];
 7 int main(){
 8     inv[0]=inv[1]=1;
 9     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
10     scanf("%d",&n);
11     for(int i=1;i<=n;i++){
12         scanf("%d",&a[i]);
13         m+=a[i];
14     }
15     g[0]=n-1;
16     for(int i=1;i<m;i++){
17         int s=(ll)(n-1)*inv[m-i]%mod;
18         g[i]=((ll)i*g[i-1]+m)%mod*s%mod;
19     }
20     for(int i=m-1;i>=0;i--)G[i]=(G[i+1]+g[i])%mod;
21     ans=mod-(ll)(n-1)*G[0]%mod;
22     for(int i=1;i<=n;i++)ans=(ans+G[a[i]])%mod;
23     ans=(ll)ans*inv[n]%mod;
24     printf("%d",ans);
25 } 
View Code

 

posted @ 2021-07-17 21:26  PYWBKTDA  阅读(52)  评论(0编辑  收藏  举报