Codeforces Round #548 D. Steps to One

自闭了,之前写的A、B找不到了QAQ。


 

Tag: 容斥,莫比乌斯函数,(DP?) 题意:给定n,每次从1到n独立等概率有放回地选一个数加到一个数组里,当数组最大公约数为1时结束,问数组期望长度是多少。 解法: 这题的做法很多,cf的题解中有一个dp的解法,思路是把用dp[x]代表现在数组的gcd=x时期望为多少,但我赛时并不是这么想的。 显然,如果要让数组尽量长,意思就是这些数都得某个数k的倍数,这样才能让$gcd(a_1,...,a_n) \equiv k \neq 1$,而这个k,显然只需要考虑是素数的情况就行。举个例子,当n=6时,我们会发现,答案似乎就等于$E(所有元素为2的倍数) + E(所有元素为3的倍数) - E(所有元素为6的倍数)$,我们不需要考虑4的倍数,因为在考虑2的倍数时已经被考虑过了。而6的倍数被考虑了两次,因此要减掉多余的一次。 具体来说,我们计算的步骤成了 1. 选择一个数k。 2. 随机生成数字直到所有数的最大公约数小于k。 3. 设选择到k的倍数的概率为p,则其期望为 $(1-p) * 0 + p * (1-p) * 1 + p^2 * (1-p) * 2 +...$   但是,这么一看,在计算期望时,是有可能序列长度为0的,而在原题中显然序列中至少会有一个元素。问题就出在我们选择一个数k时,原题中已经将这个数加入了序列。相当于序列中已经有了一个k的倍数,我们计算的期望是在这个k已经被选出来之后,额外增加的长度。   因此,稍加思考,结果就成了$1 + \Sigma_{i=1}^n E(i) * \mu (i) * (-1)$。而这个期望其实是负二项分布的期望(不懂的可以百度一下)。负二项期望是不停进行有放回的成功概率为p的抽取直到失败r次,其期望为$\frac{rp}{1-p}$,在这里$r = 1,p = \frac{n/i}{n}$。因此$E(i) = \frac{\frac{n/i}{n}}{1-\frac{n/i}{n}} = \frac{n/i}{n-n/i}$。   Codeforces Round #548 D. Steps to One
 1 ll prime[maxn],mob[maxn],vis[maxn],cnt;
 2 
 3 void Mobius(){
 4     memset(prime,0,sizeof(prime));
 5     memset(mob,0,sizeof(mob));
 6     memset(vis,0,sizeof(vis));
 7     mob[1] = 1;
 8     cnt = 0;
 9     for(ll i = 2;i < maxn;i++){
10         if(!vis[i]){
11             prime[cnt++] = i;
12             mob[i] = -1;
13 
14         }
15         for(ll j = 0;j<cnt&& i*prime[j]<maxn;j++){
16             vis[i*prime[j]] = 1;
17             if(i%prime[j]) mob[i * prime[j]] = -mob[i];
18             else {
19                 mob[i*prime[j]] = 0;
20                 break;
21             }
22         }
23     }
24 }
25 ll inv[maxn];
26 int main(){
27     ll n;
28     cin>>n;
29     Mobius();
30     inv[1] = 1;
31     for(int i = 2; i < maxn; i ++){
32         inv[i] =(mod - mod / i) * 1ll * inv[mod % i] % mod;
33     }
34     ll ans = 1;
35     for(int i = 2;i<=n;i++){
36         ll t = n * inv[n-n/i] * mob[i] * -1 % mod;
37         ans = ans * (n-n/i) + n/i * mob[i] * -1 ;
38         ans %=mod;
39         ans += mod;
40         ans %= mod;
41         ans *= inv[n-n/i];
42         ans %= mod;
43     }
44     cout<<ans<<endl;
45 }
View Code

 当然我赛时才不知道负二项分布,靠着暴力1e5求期望找规律才找到了期望公式......

上一篇:MFC一种利用全局变量来显示不同对话框的方法


下一篇:Mob云验证,让身份验证更简单