D. Zbox的刷题I

题意

\(n\) 道题,每题有 \(p\) 的概率做错,每轮所有题会一起做,其中做错的题会放到下一轮做。其中,若一轮中做了 \(x\) 道题,则产生 \(ax+b\) 的疲惫度。问期望疲惫度。


思路

考虑将 \(ax+b\) 拆成 \(ax\)\(b\) 两处贡献。

对于 \(ax\) 的部分,就是每做错一道题,就会产生 \(a\) 的贡献。

由于一直有 \(1-p\) 的概率做对,于是第一次做对的概率为 \(\large\frac1{1-p}\)。(证明见文章末尾 附加

于是这部分的贡献就是 \(\large\frac{an}{1-p}\)

然后到 \(b\) 的部分。

方法:Min-Max 容斥。

具体来说,Min-Max 容斥的式子长这样:

\[\max(S)=\sum_{T\subseteq S}(-1)^{|T|-1}\min(T) \]

其中 \(T\) 不能是空集。

那么,放到我们这题又有什么用呢?

\(S=\{1,2,...,n\}\)

我们考虑我们计算出 \(\max(S)\) 的期望,则答案就是 \(b\cdot\max(S)\)

现在我们开始推式子。

\[\begin{align} \max(S)=&\sum_{T\subseteq S}(-1)^{|T|-1}\min(T)\\ =&\sum_{k=1}^n\sum_{|T|=k,T\subseteq S}(-1)^{k-1}\min(T)\\ =&\sum_{k=1}^n\sum_{|T|=k,T\subseteq S}(-1)^{k-1}\frac{1}{1-p^k}\\ =&\sum_{k=1}^n\binom nk\frac{(-1)^{k-1}}{1-p^k}\\ \end{align} \]

其中第 \((2)\) 步是枚举 \(T\) 的大小,第 \((3)\) 步的解释也是因为有 \(k\) 道题,至少一道做对的概率是 \(1-p^k\),于是第一次的期望为 \(\large\frac1{1-p^k}\)。(证明见文章末尾 附加 )而第 \((4)\) 步是因为从 \(n\) 个数里选一个大小为 \(k\) 的集合,方案数自然为一个组合数。

于是答案就是:

\[\frac{an}{1-p}+b\cdot\max(S)=\frac{an}{1-p}-b\sum\limits_{k=1}^n\binom nk\frac{(-1)^k}{1-p^k} \]


代码

#include <bits/stdc++.h>

using namespace std;

#define int long long

#define fileio(x,y) freopen(x,"r",stdin),freopen(y,"w",stdout)
#define tup tuple<int,int,int>
#define pii pair<int,int>
#define bit(x) bitset<x>
#define pb emplace_back
#define mt make_tuple
#define mp make_pair

const int   mod=998244353;
const int   maxn=2e6+10;

int frac[maxn],invf[maxn];
int n,p;

int power(int a,int b,int p) { int tar=1; for(; b; b>>=1,a=1ll*a*a%p) if(b&1) tar=1ll*tar*a%p; return tar; }
int C(int x,int y) { return frac[x]*invf[y]%mod*invf[x-y]%mod; }

void work()
{
    /* Code */
    int a,b;
    cin>>n>>a>>b; p=a*power(b,mod-2,mod)%mod;
    cin>>a>>b;
    frac[0]=1; for(int i=1; i<=n; i++) (frac[i]=frac[i-1]*i)%=mod;
    invf[n]=power(frac[n],mod-2,mod); for(int i=n-1; i>=0; i--) (invf[i]=invf[i+1]*(i+1))%=mod;
    int tar=a*n%mod*power((mod+1-p)%mod,mod-2,mod)%mod;
    for(int i=1,base=1; i<=n; i++,(base*=p)%=mod) (tar-=(i&1? -1:1)*b*C(n,i)%mod*power((mod+1-base)%mod,mod-2,mod))%=mod;
    cout<<(tar%mod+mod)%mod<<'\n';
    return;
}

signed main()
{
    // fileio(".in",".out");
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t,stTime=clock();
    t=1;
    while(t--) work();
    // cerr<<"Time : "<<(double)(clock()-stTime)/CLOCKS_PER_SEC<<'\n';
    return 0;
} // Texas yyds !!!

附加

若有一个事件,有 \(q\) 的概率成功,\(1-q\) 的概率失败,每次做到成功就停止,否则继续。则期望执行次数为 \(\large\frac1q\)

我们考虑枚举我们失败了几次。于是就有一下式子:

\[\begin{align*} &\sum_{i=0}^\infty(1-p)^ip(i+1)\\ =p&\sum_{i=0}^\infty(1-p)^i(i+1)\\ \end{align*} \]

我们令 \(S=\sum_{i=0}\limits^\infty(1-p)^i(i+1)\)。对 \(S\) 使用扰动法,则:

\[\begin{align*} (1-p)S=&\sum_{i=0}^\infty(1-p)^{i+1}(i+1)\\ =&\sum_{i=1}^\infty(1-p)^{i}i\\ =&\sum_{i=0}^\infty(1-p)^{i}i\\ =&\sum_{i=0}^\infty(1-p)^{i}(i+1)-\sum_{i=0}^\infty(1-p)^i\\ =&S-\frac{1}{1-(1-p)}=S-\frac1p\\ \end{align*} \]

于是 \((1-p)S=S-\frac1p\),解得 \(S=\frac1{p^2}\)

所以答案就是 \(pS=\frac1p\)

当然,还有一种更直观的方法。列期望方程,设期望为 \(E\),则:

\[E=p+(1-p)(E+1) \]

解得 \(E=\frac1p\)

posted @ 2024-08-18 17:52  静谧幽蓝  阅读(5)  评论(0编辑  收藏  举报