题目链接

啊啊啊我在干什么啊。怎么这么颓一道题做这么久。。

又记错莫比乌斯反演式子了(╯‵□′)╯︵┻━┻


\(Description\)

给定\(n\)。有一个初始为空的集合\(S\)。令\(g\)表示S中所有数的\(\gcd\)。每次随机选择一个\([1,n]\)中的数加到集合\(S\)中去,直到\(g=1\)。求集合\(S\)的期望大小。(原题目描述为数列长度,\(n\)是指\(m\),我自己都看混了=-=)

\(n\leq10^5\)。

\(Solution\)

首先不要想\(f[i][j]\)这种奇奇怪怪的二维DP状态。。

令\(f[x]\)表示\(g=x\)时集合的期望大小。那么有$$\begin{aligned}f[x]&=1+\frac1n\sum_{i=1}^nf[\gcd(i,x)]\&=1+\frac1n\sum_{d\mid x}f[d]\sum_{i=1}^n[(i,x)=d]\&=1+\frac1n\sum_{d\mid x}f[d]\sum_{i=1}^{\lfloor\frac nd\rfloor}[(i,\lfloor\frac xd\rfloor)=1]\end{aligned}$$

问题在于求\(\sum_{i=1}^{\lfloor\frac nd\rfloor}[(i,\lfloor\frac xd\rfloor)=1]\)。不妨设\(g(n,k)=\sum_{i=1}^n[(i,k)=1]\)。

若限制不是\([(i,k)=1]\)而是\([x\mid (i,k)]\),显然答案就是\([x\mid k]\lfloor\frac nx\rfloor\)。

所以令\(f(d)=\sum_{i=1}^n[(i,k)=d]\),\(F(d)=\sum_{i=1}^n[d\mid(i,k)]=[d\mid k]\lfloor\frac nd\rfloor\),有$$\begin{aligned}g(n,k)=f(1)&=\sum_{i=1}n\mu(i)F(i)\&=\sum_{i=1}n\mu(i)[i\mid k]\lfloor\frac ni\rfloor\&=\sum_{d\mid k}\mu(d)\lfloor\frac nd\rfloor\end{aligned}$$

那么直接这样计算一次\(g(n,k)\)的复杂度是\(O(约数个数)\)的。\(1\sim n\)的约数个数均摊应该是\(O(\log n)\)的?

发现转移的时候两边都有\(f[x]\)。移下项,$$(1-\frac1n\sum_{i=1}^{\lfloor\frac nx\rfloor}[(i,1)=1])f[x]=1+\frac1n\sum_{d\mid x,d\neq x}f[d]\sum_{i=1}^{\lfloor\frac nd\rfloor}[(i,\lfloor\frac xd\rfloor)=1]\f[x]=\frac{1+\frac1n\sum_{d\mid x,d\neq x}f[d]\sum_{i=1}^{\lfloor\frac nd\rfloor}[(i,\lfloor\frac xd\rfloor)=1]}{1-\frac1n\lfloor\frac nx\rfloor}=\frac{n+\sum_{d\mid x,d\neq x}f[d]\sum_{i=1}^{\lfloor\frac nd\rfloor}[(i,\lfloor\frac xd\rfloor)=1]}{n-\lfloor\frac nx\rfloor}$$

这样就可以啦。答案是\(\sum_{i=1}^n\frac1nf[i]\)。

复杂度大概是\(O(n\log^2n)\)的?

还有其它更优的做法,不想看惹(甚至有线性的,瑟瑟发抖)。


//140ms	10900KB
#include <cstdio>
#include <vector>
#include <algorithm>
#define mod 1000000007
typedef long long LL;
const int N=1e5+5; int P[N>>2],mu[N],f[N],inv[N];
bool notP[N];
std::vector<int> fac[N]; inline int FP(int x,int k)
{
int t=1;
for(; k; k>>=1,x=1ll*x*x%mod) k&1&&(t=1ll*t*x%mod);
return t;
}
inline int G(int n,int k)
{
LL ans=0;
for(int i=0,l=fac[k].size(); i<l; ++i) ans+=mu[fac[k][i]]*(n/fac[k][i]);
return ans%mod;
}
void Init(const int n)
{
mu[1]=1;
for(int i=2,cnt=0; i<=n; ++i)
{
if(!notP[i]) P[++cnt]=i, mu[i]=-1;
for(int j=1,v; j<=cnt&&(v=i*P[j])<=n; ++j)
{
notP[v]=1;
if(i%P[j]) mu[v]=-mu[i];
else break;
}
}
for(int i=1; i<=n; ++i)
for(int j=i; j<=n; j+=i) fac[j].push_back(i);
} int main()
{
int n; scanf("%d",&n);
Init(n);
f[1]=1, inv[1]=1;
for(int i=2; i<=n; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int x=2; x<=n; ++x)
{
LL tmp=n;
const std::vector<int> &v=fac[x];
for(int i=0,l=v.size(),d; i+1<l; ++i) d=v[i], tmp+=1ll*f[d]*G(n/d,x/d);
f[x]=tmp%mod*inv[n-n/x]%mod;
}
LL ans=0;
for(int i=1; i<=n; ++i) ans+=f[i];
printf("%d\n",int(ans%mod*inv[n]%mod)); return 0;
}

Codeforces.1139D.Steps to One(DP 莫比乌斯反演)的更多相关文章

  1. Codeforces 1139D Steps to One dp

    Steps to One 啊, 我要死了, 这种垃圾题居然没写出来, 最后十分钟才发现错在哪. 不知道为什么我以为 对于一个数x , 除了它的因子和它的倍数都是和它互质的, 我脑子是抽了吗? 随便瞎d ...

  2. Steps to One DP+莫比乌斯反演

    卧槽,这么秀吗??? 暂时留坑...

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

    题目链接: http://codeforces.com/contest/1139/problem/D 题意: 在$1$到$m$中选择一个数,加入到一个初始为空的序列中,当序列的$gcd$和为$1$时, ...

  4. Codeforces - 1139D - Steps to One (概率DP+莫比乌斯反演)

    蒟蒻数学渣呀,根本不会做. 解法是参考 https://blog.csdn.net/xs18952904/article/details/88785210 这位大佬的. 状态的设计和转移如上面博客一样 ...

  5. CF1139D Steps to One (莫比乌斯反演 期望dp)

    \[ f[1] = 0 \] \[ f[i] = 1 + \frac{1}{m} \sum_{j = 1} ^ n f[gcd(i, j)] \ \ \ \ \ \ (i != 1) \] 然后发现后 ...

  6. 【Codeforces 809E】Surprise me!(莫比乌斯反演 & 虚树)

    Description 给定一颗 \(n\) 个顶点的树,顶点 \(i\) 的权值为 \(a_i\).求: \[\frac{1}{n(n-1)}\sum_{i=1}^n\sum_{j=1}^n\var ...

  7. 【CodeForces】915 G. Coprime Arrays 莫比乌斯反演,前缀和,差分

    Coprime Arrays CodeForces - 915G Let's call an array a of size n coprime iff gcd(a1, a2, ..., *a**n) ...

  8. 【CodeForces】915 G. Coprime Arrays 莫比乌斯反演

    [题目]G. Coprime Arrays [题意]当含n个数字的数组的总gcd=1时认为这个数组互质.给定n和k,求所有sum(i),i=1~k,其中sum(i)为n个数字的数组,每个数字均< ...

  9. Codeforces Round #548 (Div. 2) D 期望dp + 莫比乌斯反演

    https://codeforces.com/contest/1139/problem/D 题意 每次从1,m中选一个数加入队列,假如队列的gcd==1停止,问队列长度的期望 题解 概率正着推,期望反 ...

随机推荐

  1. java 日期格式化

    DateFormat DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间. SimpleDateFormat SimpleDateFormat 是一个以与 ...

  2. 【CH4302】Interval GCD

    题目大意:给定一个长度为 N 的序列,M 个操作,支持区间加,区间查询最大公约数. 题解: 先来看一个子问题,若是单点修改,区间最大公约数,则可以发现,每次修改最多改变 \(O(logn)\) 个答案 ...

  3. 项目管理——WBS工作分解法

    首先我们要了解什么是WBS工作分解法 工作分解结构(Work Breakdown Structure,简称WBS)跟因数分解是一个原理,就是把一个项目,按一定的原则分解,项目分解成任务,任务再分解成一 ...

  4. HDU2859 Phalanx (动态规划)

    Today is army day, but the servicemen are busy with the phalanx for the celebration of the 60th anni ...

  5. 消息框MessageBox+遍历控件

    消息对话框:主要用来显示信息,也可以警告.用户确认取消等. MessageBox.Show("展示内容","标题",MessageBoxButtons.按钮种类 ...

  6. JS学习笔记Day13

    一.cookie (一)什么是cookie: 1.就是会话跟踪技术,存放在客户端浏览器中的一段文本信息 2.会话:从浏览网站开始到结束的这个过程称为一次会话,浏览器关闭,表示会话结束 3.会话跟踪技术 ...

  7. GO语言系列(五)- 结构体和接口

    结构体(Struct) Go中struct的特点 1. 用来自定义复杂数据结构 2. struct里面可以包含多个字段(属性) 3. struct类型可以定义方法,注意和函数的区分 4. struct ...

  8. java io系列17之 System.out.println("hello world")原理

    我们初学java的第一个程序是"hello world" public class HelloWorld { public static void main(String[] ar ...

  9. 常用的消息队列中间件mq对比

    原文地址:https://blog.csdn.net/qq_30764991/article/details/80239076 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量 ...

  10. Best Practice API

    # 建议直接使用的第三方类 Common Lang =>StringUtils =>Validate Guava =>Cache =>Ordering JDK7(LTS JDK ...