题解 P5081 【Tweetuzki 爱取球】

· · 题解

题解思路:正难则反

我们发现,因为该期望的概率数列是个不收敛数列,所以要想顺着题目的思路去推出期望几乎是不可能的,因此我们要另辟蹊径

引理:

求证

假设对于一件事A,我们每一次做A时的成功率是P,如果本次不成功就继续做,最终期望\dfrac{1}{p}次做成

证明:

对于这个问题,我们显然不能正向去想,我们可以利用一个叫做递归公式的东西:我们设期望k次做成A ,则有:

k=1+p*0+(1-p)*k

其中1表示第一次做A,如果成功了就再做0次,期望次数为p*0;如果不成功就再做k次,期望为(1-p)*k

通过移项,我们得到

k=\dfrac {1}{p}

引理证毕

正文:

我们先来思考一个问题:n个球里取出1个球的概率是多少

答案很简单,显然是1,由引理得,取出1个球成功的期望次数为k_1=\dfrac{1}{p}=\dfrac{1}{1}=1

n个球中取出其他n-1个球中的一个球的概率呢?其实也很好算,就是\dfrac{n-1}{n},那成功的期望次数就是k_2=\dfrac{1}{p}=\dfrac{n-1}{n}

以此类推……………………

取遍这n个球的总期望次数为:k_{sum}=k_1+k_2+\text{…}+k_n=\dfrac{n}{n}+\dfrac{n}{n-1}+\text{…}+\dfrac{n}{1}=n*\sum\limits_{i=1}^{n-1}\dfrac{1}{n-i}

所以最终这个题就是求个逆元和乘n就完事了

附加证明:线性筛逆元

我们知道,对于任意一个数p,都有p=a*b+ca,b,c为任意整数)

则对于式子p\equiv0\text{(mod p)}

我们有a*b+c\equiv0\text{(mod p)}

c挪到右边:a*b\equiv-c\text{(mod p)}

两边同时乘c的逆元c^{-1}a*b*c^{-1}\equiv-1\text{(mod p)}

两边再同时乘b的逆元b^{-1}a*c^{-1}\equiv-b^{-1}\text{(mod p)}

即可化为b^{-1}\equiv-a*c^{-1}\text{(mod p)}

同时,我们知道,在c++里,int类的除法都是自动向下取整的。所以我们可以得到:对于数p=a*b+c,有a=\dfrac{p}{b}c=p\%b(我们要求的是b的逆元,p是模数)。我们设inv[i]i的逆元,则有递推式:

inv[i]=(1ll*(p-\dfrac{p}{i})*inv[p\%i])\%p

证毕

以下是code:

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int p=20040313;
ll inv[10000010],sum,n;
int main()
{
    scanf("%lld",&n);
    inv[1]=1;sum+=1;
    for(int i=2;i<=n;i++)//简短有力
    inv[i]=(1ll*(p-p/i)*inv[p%i])%p,sum=(sum+inv[i])%p;
    printf("%lld",n*sum%p);
    return 0;
}