题目链接:
http://codeforces.com/contest/1139/problem/D
题意:
在$1$到$m$中选择一个数,加入到一个初始为空的序列中,当序列的$gcd$和为$1$时,停止加入,求序列的期望长度
数据范围:
$1 \leq m \leq 10^{9}$
分析:
定义$f[x$]为$gcd$等于$x$时把序列$gcd和$改变成1的期望长度,定义$G(x,y)$为$i$在1到$n$范围,满足$gcd(x,i)=y$,$i$的数量,得到以下公式:
$$f[i]=1+\frac{\sum_{d|i}f[d]\times G(i,d)}n,x=i$$
由于公式两边都有$f[i]$(因为$i|i$),所以对公式进行变换:
$$f[i]=1+\frac{\sum_{d|i,d
$$\frac{n-G(i,i)}{n}\cdot f[i]=1+\frac{\sum_{d|i,d
$$f[i]=\frac{n+\sum_{d|i,d
然后就是用莫比乌斯反演快速求出$G(x,y)$即可
$$G(x,y)=\sum_{d|\frac xy}\mu(d)\left\lfloor\frac{n}{d*y}\right\rfloor$$
ac代码:
#include
#define ll long long
using namespace std;
const int maxn=1e5+10;
const int mod=1e9+7;
ll f[maxn],n;
int pri[maxn],mu[maxn],is[maxn],cnt;
vectorve[maxn];
int cal(int x,int y)//i 在 1-n gcd(x,i)=y;
{
int dd=x/y,res=0;
for(int i=0;i