[题目链接]

https://codeforces.com/contest/1139/problem/D

[算法]

考虑dp

设fi表示现在gcd为i , 期望多少次gcd变为1

显然 , fi = (1 / m) * sigma{ fgcd(i , j) } + 1

直接转移是O(N ^ 2logN)的 , 显然不能通过

考虑在转移时枚举gcd , 显然gcd只可能是i的约数 , 可以在dp前O(NlogN)预处理每个数的约数

于是问题转化为求一个形如 : [1 , m]中有多少个数与i的gcd为j的问题

这等价于求 : [1 , m / j]中有多少个数与(i / j)的gcd为1

容斥原理计算即可

时间复杂度 : O(NlogN)( 有较大的常数 )

[代码]

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef long double ld;
  5. typedef unsigned long long ull;
  6. const int P = 1e9 + ;
  7. const int MAXP = 1e5 + ;
  8.  
  9. #define rint register int
  10.  
  11. int m , tot;
  12. int f[MAXP] , prime[MAXP] , dp[MAXP];
  13. vector< int > d[MAXP];
  14.  
  15. template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
  16. template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
  17. template <typename T> inline void read(T &x)
  18. {
  19. T f = ; x = ;
  20. char c = getchar();
  21. for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
  22. for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
  23. x *= f;
  24. }
  25. inline int exp_mod(int a , int n)
  26. {
  27. int b = a , res = ;
  28. while (n > )
  29. {
  30. if (n & ) res = 1LL * res * b % P;
  31. b = 1LL * b * b % P;
  32. n >>= ;
  33. }
  34. return res;
  35. }
  36. inline int calc(int N , int M)
  37. {
  38. vector< int > pr;
  39. int tmp = N / M;
  40. while (tmp != )
  41. {
  42. pr.push_back(f[tmp]);
  43. tmp /= f[tmp];
  44. }
  45. int sz = unique(pr.begin() , pr.end()) - pr.begin();
  46. int limit = m / M , res = ;
  47. for (int i = ; i < ( << sz); ++i)
  48. {
  49. int sign = , val = ;
  50. for (int j = ; j < sz; ++j)
  51. {
  52. if (i & ( << j))
  53. {
  54. sign *= -;
  55. val *= pr[j];
  56. }
  57. }
  58. res += 1LL * sign * (limit / val);
  59. }
  60. return res;
  61. }
  62.  
  63. int main()
  64. {
  65.  
  66. read(m);
  67. for (rint i = ; i <= m; ++i)
  68. {
  69. for (rint j = i; j <= m; j += i)
  70. {
  71. d[j].push_back(i);
  72. }
  73. }
  74. for (rint i = ; i <= m; ++i)
  75. {
  76. if (!f[i])
  77. {
  78. prime[++tot] = i;
  79. f[i] = i;
  80. }
  81. for (int j = ; j <= tot; ++j)
  82. {
  83. int tmp = i * prime[j];
  84. if (tmp >= MAXP) break;
  85. f[tmp] = prime[j];
  86. if (prime[j] == f[i]) break;
  87. }
  88. }
  89. dp[] = ;
  90. for (rint i = ; i <= m; ++i)
  91. {
  92. int res = ;
  93. for (unsigned j = ; j < d[i].size(); ++j)
  94. {
  95. int D = d[i][j];
  96. if (D != i) res = (res + 1LL * calc(i , D) * dp[D] % P) % P;
  97. }
  98. res = 1LL * res * exp_mod(m , P - ) % P;
  99. res = (res + ) % P;
  100. int fm = m - calc(i , i);
  101. res = 1LL * res * exp_mod(fm , P - ) % P * m % P;
  102. dp[i] = res;
  103. }
  104. int ans = ;
  105. for (rint i = ; i <= m; ++i) ans = (ans + 1LL * exp_mod(m , P - ) * dp[i] % P) % P;
  106. printf("%d\n" , ans);
  107.  
  108. return ;
  109.  
  110. }

[Codeforces 1139D] Steps to One的更多相关文章

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

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

  2. Codeforces 1139D Steps to One dp

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

  3. Codeforces.1139D.Steps to One(DP 莫比乌斯反演)

    题目链接 啊啊啊我在干什么啊.怎么这么颓一道题做这么久.. 又记错莫比乌斯反演式子了(╯‵□′)╯︵┻━┻ \(Description\) 给定\(n\).有一个初始为空的集合\(S\).令\(g\) ...

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

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

  5. Codeforces 1139D(期望dp)

    题意是模拟一个循环,一开始有一个空序列,之后每次循环: 1.从1到m中随机选出一个数字添加进去,每个数字被选的概率相同. 2.检查这个序列的gcd是否为1,如果为1则停止,若否则重复1操作直至gcd为 ...

  6. Codeforces 1139D(推式子+dp)

    题目传送 推公式博客传送 推完式子就是去朴素地求就行了Orz const int maxn = 1e5 + 5; const int mod = 1e9 + 7; int m, mu[maxn], v ...

  7. 【Codeforces1139D_CF1139D】Steps to One (Mobius_DP)

    Problem: Codeforces 1139D Analysis: After ACing E, I gave up D and spent the left 30 minutes chattin ...

  8. Codeforces Round #321 (Div. 2) A. Kefa and First Steps 水题

    A. Kefa and First Steps Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/58 ...

  9. Codeforces #548 (Div2) - D.Steps to One(概率dp+数论)

    Problem   Codeforces #548 (Div2) - D.Steps to One Time Limit: 2000 mSec Problem Description Input Th ...

随机推荐

  1. ProjectManager Beta 7 项目管理器发布

    上次在Alpha阶段有一个可用版本Alpha 8也在这个博客发布了,传送:http://www.cnblogs.com/deali/p/ProjectManager.html ProjectManag ...

  2. SpringBoot启动流程分析(六):IoC容器依赖注入

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  3. PAT 1061. 判断题(15)

    判断题的评判很简单,本题就要求你写个简单的程序帮助老师判题并统计学生们判断题的得分. 输入格式: 输入在第一行给出两个不超过100的正整数N和M,分别是学生人数和判断题数量.第二行给出M个不超过5的正 ...

  4. 关于随机浏览头伪装fake-UserAgent

    使用: from fake_useragent import UserAgent ua = UserAgent() #ie浏览器的user agent print(ua.ie) Mozilla/5.0 ...

  5. 3.16课·········C#小结

    //附加//C#源码,被C#编译器,编译成执念代码(IL)//int16=short.....±32000//int32=int.......±21亿//int64=long......±922亿亿3 ...

  6. 在linux系统下Git源码系统的文件下载

    Git是一个开源的分布式版本控制系统,在linux系统中下载git中的文件使用repo的很多. 网上有很多repo下载的地址失效,目前可用的链接在这里记录一下. 没有安装git的安装一下: sudo ...

  7. mysql innobackupex备份实施

    最近用innobackup进行备份测试,我们只备份一个innodb类型的库,数据大小大概50多G,用innobackupex大概用了5个多小时,但是mysqldump只用了大约2个小时,这让我很费解, ...

  8. Spring层面的事务管理

    事务管理方式 1. 编程式事务管理 2. 声明式事务管理 建立于AOP之上,对指定的方法执行前后进行拦截,即在方法执行前开始或加入一个事务,执行完毕后根据结果提交或回滚事务. 方式: a. 配置文件中 ...

  9. Get Docker CE for Ubuntu

    Docker 分为开源免费的 CE(Community Edition)版本和收费的 EE(Enterprise Edition)版本. 配置 Docker 的 apt 源 1. 安装包,允许 apt ...

  10. CentOS下查看MySQL的安装路径

    Linux下查看mysql.apache是否安装,并卸载. 指令 ps -ef|grep mysql 得出结果 root     17659     1  0  2011 ?        00:00 ...