以下是我这道题的思考过程:
(1)、若选到1,那直接就能结束了。
(2)、若选到其他的数,则我们需要继续选下去,直到选到一个和前面的一个数互质的数。想到互质,可以想到和质数相关。
思考极限情况,我们可以想象这一过程:不停地选数,在这个过程在,我们保持选到的数的都是某一个数x的倍数,直到选到一个数不为x的倍数就结束。
这一过程其实就是概率论中的负二项式分布:

  1. 实验包含一系列独立的实验。
  2. 每个实验都有成功、失败两种结果。
  3. 成功的概率p是恒定的。
  4. 实验持续到r次失败,r可以为任意正数。

则X~NB(r,p),并且E(X)=rp1−pE(X)={rp\over 1-p}E(X)=1−prp​
(摘自百度百科)
因此,我们可以枚举x,算出p,再对所有的E求和就是答案了。
但是我们发现如果我们令x取遍1~m会存在重复,因为m的倍数和m的因数的倍数之间存在重复,联想之前的质数,我们容易联想到我们可以只枚举质数。但是,仍然有重复,如6同时是2和3的倍数,因此还需要容斥。根据容斥的公式,一个数若含有奇数个次数为1的质因子则+E,若含有偶数个次数为1的因子则-E,这就和莫比乌斯函数有关。
因此,公式如下:
ANS=1+∑i=2mμ(i)E(i)ANS=1+\sum_{i=2}^m\mu(i)E(i)ANS=1+i=2∑m​μ(i)E(i)
E(i)=p1−p=⌊mi⌋m1−⌊mi⌋mE(i)={p\over{1-p}}={{{\lfloor{m\over i}\rfloor}\over m}\over{1-{\lfloor{m\over i}\rfloor\over m}}}E(i)=1−pp​=1−m⌊im​⌋​m⌊im​⌋​​
cf的直接套上去就能过了。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(int i = a; i <= n; ++ i)
#define per(i, a, n) for(int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{if(x<0){putchar('-');x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');
}template<typename T> void read(T &x)
{x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
inline int ksm(int a,int n){int ans=1;while(n){if(n&1) ans=(1ll*ans*a)%mod;a=1ll*a*a%mod;n>>=1;}return ans%mod;
}
//==============================================================
const int maxn=1e5+10;
int m;
bool vis[maxn];
int pri[maxn],tot;
int mu[maxn];
void init(){mu[1]=1;for(int i=2;i<maxn;++i){if(!vis[i])pri[++tot]=i,mu[i]=mod-1;for(int j=1;j<=tot&&i*pri[j]<maxn;++j){vis[i*pri[j]]=1;if(i%pri[j]==0)break;mu[i*pri[j]]=mod-mu[i];}}
}int solve(){int res=1;for(int i=2;i<=m;++i){int p=1ll*(m/i)*ksm(m,mod-2)%mod;res+=1ll*(mod-mu[i])*p%mod*ksm(1-p,mod-2)%mod;res=(res%mod+mod)%mod;}return res;
}signed main()
{#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endif//clock_t c1 = clock();//===========================================================read(m);init();cout<<solve()<<endl;//===========================================================//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;return 0;
}

天体赛的话还需要继续优化。可以看到数据范围高达1e11,八成是要亚线性筛。对于上式,最先想到的应该是数论分块,而还需要一个莫比乌斯函数前缀和,因此,上杜教筛。记得开int128。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(int i = a; i <= n; ++ i)
#define per(i, a, n) for(int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
typedef long long ll;
typedef __int128 i128;
#define int ll
ll mod=1e9+7;
using namespace std;
template<typename T>void write(T x)
{if(x<0){putchar('-');x=-x;}if(x>9){write(x/10);}putchar(x%10+'0');
}template<typename T> void read(T &x)
{x = 0;char ch = getchar();int f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
inline i128 ksm(i128 a,i128 n){i128 ans=1;while(n){if(n&1) ans=((i128)ans*a)%mod;a=(i128)a*a%mod;n>>=1;}return ans%mod;
}
//==============================================================
ll n;
inline i128 mul(i128 a,i128 b){return (i128)a*b%mod;
}inline i128 add(i128 a,i128 b){return a+b>=mod?a+b-mod:a+b;
}inline i128 sub(i128 a,i128 b){return (a-b+mod)>=mod?a-b:a-b+mod;
}const int maxn=2e7+10;
bool vis[maxn];
int pri[maxn],tot;
int mu[maxn];
inline void init(){mu[1]=1;for(int i=2;i<maxn;++i){if(!vis[i])pri[++tot]=i,mu[i]=mod-1;for(i128 j=1;j<=tot&&i*pri[j]<maxn;++j){vis[i*pri[j]]=1;if(i%pri[j]==0){break;}mu[i*pri[j]]=mod-mu[i];}}for(i128 i=1;i<maxn;++i){mu[i]=add(mu[i],mu[i-1]);}
}
unordered_map<ll,i128>dpmu;
i128 SumMu(ll n){if(n<maxn)return mu[n];if(dpmu.count(n))return dpmu[n];ll res=1;for(ll l=2,r;l<=n;l=r+1){ll t=n/l;r=n/t;res=sub(res,mul(r-l+1,SumMu(n/l)));//res=(res-(r-l+1)*SumMu(n/l)%mod+mod)%mod;}return dpmu[n]=res;
}
inline i128 solve(){i128 res=1;i128 pre=SumMu(1);for(ll l=2,r;l<=n;l=r+1){i128 now=n/l;r=n/now;i128 pos=SumMu(r);i128 p=mul((n/l),ksm(n,mod-2));res=add(res,mul(mul(((mod-(pos-pre))),p),ksm(1-p,mod-2)));pre=pos;}return (res%mod+mod)%mod;
}signed main()
{#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endif//clock_t c1 = clock();//===========================================================read(n),read(mod);init();write(solve());//===========================================================//std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;return 0;
}

Codeforces Round #548 (Div. 2) 1139 D+2021天梯赛l3-3 解题报告(负二项式分布+莫比乌斯容斥+杜教筛(天梯赛))相关推荐

  1. 【Codeforces Round #565 (Div. 3) A B C D E F】解题报告

    Codeforces 565 失踪人口回归 cf 565 A 题意 你可以把一个偶数变成 n/2 , 可以把一个3的倍数变成 n2/3, 可以把一个5的倍数变成 n4/5 问你最少通过多少步可以变成1 ...

  2. # Codeforces Round #548 (Div. 2)C Edgy Trees

    Codeforces Round #548 (Div. 2)C Edgy Trees 题目传送门 You are given a tree (a connected undirected graph ...

  3. Codeforces Round #548 (Div. 2) C. Edgy Trees(dfs || 并查集)

    题目链接:https://codeforces.com/contest/1139/problem/C 题意:给了一棵树,n个点,m条边.让从中选k个点,使得从a1到a2,a2到a3,ak-1到ak的路 ...

  4. Codeforces Round #548 (Div. 2)C. Edgy Trees 并查集

    codeforces 1139C 题目链接:http://codeforces.com/contest/1139/problem/C 题意: 给你一个n个结点n-1条边的无向连通图,由红边和黑边组成. ...

  5. C. Edgy Trees---(思维题+并查集的运用)---Codeforces Round #548 (Div. 2)

    Edgy Trees time limit per test 2 seconds memory limit per test 256 megabytes 题目链接http://codeforces.c ...

  6. Codeforces Round #548 (Div. 2) C. Edgy Trees(思维+dfs)

    题目链接:https://codeforces.com/contest/1139/problem/C        题意是给了一棵树,n个点,m条边.让从中选k个点,使得从a1到a2,a2到a3,ak ...

  7. [题解][Codeforces 1139A~1139F]Codeforces Round #548 (Div. 2) 简要题解

    终于 rank < 10 了 题目 洛谷 RemoteJudge A B C D E F Codeforces A B C D E F A 题意 一个长度为 nnn 的数字串 sss 求 sss ...

  8. C. Edgy Trees Codeforces Round #548 (Div. 2) 【连通块】

    一.题面 here 二.分析 这题刚开始没读懂题意,后来明白了,原来就是一个数连通块里点数的问题.首先在建图的时候,只考虑红色路径上的点.为什么呢,因为为了不走红色的快,那么我们可以反着想只走红色的路 ...

  9. Codeforces Round #548 (Div. 2) A. Even Substrings

    You are given a string ?=?1?2-??s=s1s2-sn of length ?n, which only contains digits 11, 22, ..., 99. ...

  10. 【Codeforces Round #548(Div. 2)】Edgy Trees(数学+bfs求连通块)

    题目链接 C. Edgy Trees time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

最新文章

  1. SAP MIGO 报错-在例程WERT_SIMULIEREN字段NEUER_PREIS中字段溢出-
  2. skyeye linux qt,ARM仿真器SkyEye的安装及使用
  3. 如何让 python 处理速度翻倍?内含代码
  4. ElasticSearch启动报错,报ERROR: [3] bootstrap checks failed
  5. JSK-389 同因查找【入门】
  6. Python字符串中常用的方法
  7. 利用 Google Chart API 生成二维码大小不一致
  8. IDEA查看或修改JDK版本
  9. Cathy学Java——数据库
  10. AD15PCB快速布局元器件
  11. 背景建模之codebook算法
  12. 【因果推断的统计方法】观察性研究和可忽略性
  13. vue使用百度地图获取位置信息
  14. Houdini abcobj 导入 Maya
  15. 算法竞赛入门【码蹄集进阶塔335题】(MT2076-2100)
  16. 湘潭2017 ccpc中南地区邀请赛 Determinant 高斯约当求逆矩阵
  17. 应广单片机PFS123按键中断控制数码管显示例程
  18. 嵌入式主板有哪些特点?
  19. PS出现“不能完成命令,因为没有足够内存(RAM)”的解决方案
  20. 推荐系统 - 基于FM算法的协同召回算法

热门文章

  1. 阿里面试:设计一个电商平台积分兑换系统!
  2. php源码字符串内部表示,PHP源码—implode函数源码分析
  3. 【饭谈】【超详细】的资深测开的招聘要求,大家看看这符合了值多少钱?
  4. openfiler服务器打不开web管理页面
  5. Github年度百大框架排行榜
  6. 路由器怎么用自己的笔记本电脑进行配置
  7. rap开发与rcp开发_使用RAP将RCP应用程序转换为Web应用程序
  8. 红色警戒常用的快捷键
  9. 软件生命周期和开发模型
  10. c 语言count函数什么意思,在C ++ STL中设置count()函数