codeforces#1139D. Steps to One (概率dp+莫比乌斯反演)

题目链接:

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

  

 

转载于:https://www.cnblogs.com/carcar/p/10689260.html

你可能感兴趣的:(codeforces#1139D. Steps to One (概率dp+莫比乌斯反演))