【ybt金牌导航8-4-1】整数个数 / 欧拉函数例题

整数个数

题目链接:ybt金牌导航8-4-1

题目大意

给你一个数 n,求满足一下条件的数个数:
要小于 n,要不是 n 的约数,不能与 n 互质。

思路

你看到互质,自然会想到欧拉函数。

但是它是不能互质啊,而且它说不是约数也很烦。

那简单,我们容斥一下,用全部的(根据小于 nn1 个)减去是 n 的约数n 互质的个数就好了。

那算约数的时候你会把 n 也算作约数,但你前面的条件是小于 n,那就要继续容斥,这里算的是减的,那你就要加回一个 1

然后你算约数和算互质的时候会都算到 1,那也容斥,加回 1

那这样就可以直接减约数个数和互质个数再根据上面容斥就可以了。

接着就是怎么求互质个数,也就是欧拉函数要怎么算。

这里给出一种算单个的方法。
φ(i)=i×p11p1×...×pm1pm
pi 是它的质数因子)

原理大概就是它不能出现任何因子,而因子由素数因子构成。
然后就类似容斥,你某个质数 pi1i 划分成许多长度为 pi 的区间,然后每个区间都有个位置不能选(就是那个位置是 pi 的倍数)。
然后每个质数因子都这样,就是这个公式了。

代码

#include<cstdio> #define ll long long using namespace std; ll n, ans; ll phi(ll x) {//求n的phi值 int re = x; for (int i = 2; i * i <= x; i++) if (n % i == 0) { re = re / i * (i - 1); while (n % i == 0) n /= i; } if (n >> 1) re = re / n * (n - 1); return re; } int main() { scanf("%d", &n); ans = n - 1;//满足小于 n 的有 n-1 个 for (ll i = 1; i * i <= n; i++)//求 n 因子的个数 if (n % i == 0) { ans -= 2; if (i * i == n) ans++; } ans++;//前面求的时候把 n 也算个进去,减多了,要加回去 ans -= phi(n);//求与 n 互质的数的个数(n 的 phi 值) ans++;//求因子和求互质的地方都算了 1,重复了要加回去。 printf("%lld\n", ans); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_8-4-1.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(54)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示