博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj2440(莫比乌斯函数)
阅读量:6425 次
发布时间:2019-06-23

本文共 1631 字,大约阅读时间需要 5 分钟。

题意

求第 k 个不是完全平方数(除 1 以外)的正倍数的数。

分析

利用二分法求解,二分 x ,判断 x 是否是第 k 个数即可,那么我们就要计算 [1, x] 有几个符合条件的数。

首先本题用到容斥原理的思想,
sum = 1 的倍数的数的个数 - (4, 8, 9, ) 这些质因子个数为 1 的平方的倍数的数的个数 + (36, ) 这些质因子个数为 2 的平方的倍数的数的个数 ...

而根据莫比乌斯函数 \(\mu(n)\) 的定义:

\(n = p_1 ^ {k_1} \cdot p_2 ^ {k_2} \cdot\cdots\cdot p_m ^ {k_m}\) ,其中 p 为素数,则定义如下:
\(\mu(n) = \begin{cases} 1 & n = 1 \\ (-1) ^ m & \prod\limits_{i = 1} ^ {m} k_i = 1 \\ 0 & \textrm{otherwise}(k_i \gt 1) \end{cases}\)
最终得到下面的式子:
\(sum = \sum_{i=1}^{\left \lfloor \sqrt{x} \right \rfloor}\mu(i)\left \lfloor \frac{x}{i^{2}}\right \rfloor\)

我们可以通过线性筛来求出莫比乌斯函数的值。

code

#include
using namespace std;typedef long long ll;const int MAXN = 1e6 + 10;int not_prime[MAXN];int prime[MAXN];int mu[MAXN];void getMu() { mu[1] = 1; int cnt = 0; for(int i = 2; i < MAXN; i++) { if(!not_prime[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j = 0; i * prime[j] < MAXN; j++) { not_prime[i * prime[j]] = 1; if(i % prime[j] == 0) { mu[i * prime[j]] = 0; break; } mu[i * prime[j]] = -mu[i]; } }}ll cal(ll x) { ll s = 0; for(ll i = 1; i * i <= x; i++) { s += mu[i] * (ll)(x / (i * i)); } return s;}int main() { getMu(); int T; cin >> T; while(T--) { ll k; cin >> k; ll l = 1, r = 1e10, mid = (l + r) / 2; while(l < r) { if(cal(mid) >= k) r = mid; else l = mid + 1; mid = (l + r) / 2; } cout << mid << endl; } return 0;}

转载于:https://www.cnblogs.com/ftae/p/6995466.html

你可能感兴趣的文章
struts2.0的json操作
查看>>
SQL注入神器——sqlmap
查看>>
Unity导航 (寻路系统Nav Mesh Agent)
查看>>
SaltStack配置语法-YAML和Jinja
查看>>
运用免费OA让你有意想不到的效果
查看>>
一些软件设计软则
查看>>
Linux运维基础命令
查看>>
使用PowerShell配置IP地址
查看>>
第十一章 MySQL运算符
查看>>
JAVA常见算法题(十七)
查看>>
GUI鼠标相关设置
查看>>
使用 <Iframe>实现跨域通信
查看>>
闭包--循序学习
查看>>
项目实战之集成邮件开发
查看>>
解决C3P0在Linux下Failed to get local InetAddress for VMID问题
查看>>
1531 山峰 【栈的应用】
查看>>
巧用美女照做微信吸粉,你会做吗?
查看>>
wcf学习总结《上》
查看>>
ERROR (ClientException)
查看>>
Load Balance 产品横向比较
查看>>