HDU 4135 Co-prime
题意:求区间
[a,b]
中与m
互素的数字个数
一、题目分析
考虑[1,a-1]
和[1,b]
两个区间与m
互素的个数,答案就是二者之差(类似前缀和?)。
容斥原理经典问题:求1-n
中与m
互素的数的个数
互素的个数等于总数减去不互素的个数,如果中某个数与不互素,那么一定可以被的某个因子整除,所以先枚举的所有素因子。
举个例子,,的素因子是,
中有几个是的倍数呢?;
中有几个是的倍数呢?;
之间与互素的个数是个数字吗?
之间与不互素的是,共个数字,这是因为同为和的倍数的被计算了两次,所以要再减去一次,结果是
这是经典的容斥原理啊,如果是奇数个组合,那么符号是+
;如果是偶数个组合,那么符号是-
;
二、实现代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
//返回1-m中与n互素的数的个数
vector<LL> p;
LL cal(LL n, LL m) {
p.clear();
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
p.push_back(i);
while (n % i == 0) n /= i;
}
}
if (n > 1) p.push_back(n); //求n的素因子
int num = p.size(); //素因子的个数
LL s = 0; // 1到m中与n不互素的数的个数
//枚举子集,不能有空集,所以从1开始
for (LL i = 1; i < 1 << num; i++) { //从1枚举到(2^素因子个数)
LL cnt = 0;
LL t = 1;
for (LL j = 0; j < num; j++) { //枚举每个素因子
if (i & (1 << j)) { //有第i个因子
cnt++; //计数
t *= p[j]; //乘上这个质因子
}
}
//容斥原理
if (cnt & 1) //选取个数为奇数,加
s += m / t;
else //选取个数为偶数,减
s -= m / t;
}
return m - s; //返回1-m中与n互素的数的个数
}
int main() {
//加快读入
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T, ca = 0;
cin >> T;
while (T--) {
LL m, a, b;
cin >> a >> b >> m; //求区间[a,b]中与m互素的数字个数
//计算[1,a-1]之间与m互素的个数
//计算[1, b]之间与m互素的个数
LL ans = cal(m, b) - cal(m, a - 1);
printf("Case #%d: %lld\n", ++ca, ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2019-06-20 https跳http
2017-06-20 研修项目文件丢失的处理思路
2017-06-20 安装配置GitLab
2016-06-20 使用Nginx+FFMPEG搭建HLS直播转码服务器