[题目链接]

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)( 有较大的常数 )

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int P = 1e9 + ;
const int MAXP = 1e5 + ; #define rint register int int m , tot;
int f[MAXP] , prime[MAXP] , dp[MAXP];
vector< int > d[MAXP]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline int exp_mod(int a , int n)
{
int b = a , res = ;
while (n > )
{
if (n & ) res = 1LL * res * b % P;
b = 1LL * b * b % P;
n >>= ;
}
return res;
}
inline int calc(int N , int M)
{
vector< int > pr;
int tmp = N / M;
while (tmp != )
{
pr.push_back(f[tmp]);
tmp /= f[tmp];
}
int sz = unique(pr.begin() , pr.end()) - pr.begin();
int limit = m / M , res = ;
for (int i = ; i < ( << sz); ++i)
{
int sign = , val = ;
for (int j = ; j < sz; ++j)
{
if (i & ( << j))
{
sign *= -;
val *= pr[j];
}
}
res += 1LL * sign * (limit / val);
}
return res;
} int main()
{ read(m);
for (rint i = ; i <= m; ++i)
{
for (rint j = i; j <= m; j += i)
{
d[j].push_back(i);
}
}
for (rint i = ; i <= m; ++i)
{
if (!f[i])
{
prime[++tot] = i;
f[i] = i;
}
for (int j = ; j <= tot; ++j)
{
int tmp = i * prime[j];
if (tmp >= MAXP) break;
f[tmp] = prime[j];
if (prime[j] == f[i]) break;
}
}
dp[] = ;
for (rint i = ; i <= m; ++i)
{
int res = ;
for (unsigned j = ; j < d[i].size(); ++j)
{
int D = d[i][j];
if (D != i) res = (res + 1LL * calc(i , D) * dp[D] % P) % P;
}
res = 1LL * res * exp_mod(m , P - ) % P;
res = (res + ) % P;
int fm = m - calc(i , i);
res = 1LL * res * exp_mod(fm , P - ) % P * m % P;
dp[i] = res;
}
int ans = ;
for (rint i = ; i <= m; ++i) ans = (ans + 1LL * exp_mod(m , P - ) * dp[i] % P) % P;
printf("%d\n" , ans); return ; }

[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. java并发编程基础---Sky

    1.线程及启动和终止 1.1 线程 -进程/优先级 操作系统调度的最小单元是线程,线程是轻量级进程. 线程优先级由setPriority(int)方法来设置,默认优先级是5,等级1~10.等级越高分的 ...

  2. openssl将私钥和crt证书合成pfx证书

    pfx是什么文件:公钥加密技术12号标准(Public Key Cryptography Standards #12,PKCS#12)为存储和传输用户或服务器私钥.公钥和证书指定了一个可移植的格式.它 ...

  3. 页游手游服务器(二)c支持mysql

    上一篇说的是liua的net拓展,这一篇说lua的sql拓展,准确说是mysql拓展,这里推荐下postgre,比mysql好用,支持数组,各种好,不过腾讯平台不支持,所以你的公司要和腾讯合作,掂量下 ...

  4. cordova 获取地理位置

    第一步,引入插件 cordova plugin add cordova-plugin-geolocation 第二步, <!DOCTYPE html> <html> <h ...

  5. QT设置textEdit光标到末尾

    //移动光标到末尾 QTextCursor cursor = ui->receiveTextEdit->textCursor(); cursor.movePosition(QTextCur ...

  6. 使用Imagemagick批量加水印缩小图片的脚本

    安装Imagemagick首先要安装Imagemagick 本文HTML永久地址 doc CentOS上安装 yum install ImageMagick -yDebian上安装 apt-get i ...

  7. linux sort按照指定列排序

    sort怎样按指定的列排序0000 27189 41925425065f 15 419254250663 7 419254250675 5 419254250691 76 419254250693 2 ...

  8. simple -- abstract

    <?php abstract class Operation { protected $_NumberA = 0; protected $_NumberB = 0; protected $_Re ...

  9. Elatsicsearch分片和副本相关知识

    1.分片和副本 1.1什么是分片 简单来讲就是咱们在ES中所有数据的文件块,也是数据的最小单元块,整个ES集群的核心就是对所有分片的分布.索引.负载.路由等达到惊人的速度. 分片是把索引数据切分成多个 ...

  10. sublime-text 键绑定

    vim 和 emacs 是牛人们的两大神器,sublime-text则是每个人的编程利器. 先说一下本人的感受,vim用了一段时间,emacs也小试了一下,两大神器尽是各种命令,另人眼花缭乱. 但是有 ...