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}$。
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求期望找规律才找到了期望公式......
标签:期望,ll,Codeforces,Steps,倍数,mob,frac,548,maxn 来源: https://www.cnblogs.com/regen/p/10578166.html