hdu 4135 Co-prime(容互原理 DFS+位运算求解)
来源:互联网 发布:mac系统安装软件 编辑:程序博客网 时间:2024/05/21 07:57
hdu 4135 Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6051 Accepted Submission(s): 2411
Problem Description
Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.
Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
Input
The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 1015) and (1 <=N <= 109).
Output
For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
Sample Input
2
1 10 2
3 15 5
Sample Output
Case #1: 5
Case #2: 10
Hint
In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
Source
The Third Lebanese Collegiate Programming Contest
Recommend
lcy | We have carefully selected several similar problems for you: 1796 1434 3460 1502 4136
题解
给出区间【A,B】和数字n 求解 与n互质的数的个数(即与n没有公约数的数的个数),1 <= A <= B <= 10^15 显然不能用暴力求解,所以用到容斥
下面我们一步一步来进行分析:
1 求【A,B】区间与k互质的个数转化成求解【1,B】区间中与n互斥的个数减去【1,A-1】中与k互斥的个数 (A-1 是因为要把A算进去)
2. 接下来问题转化成为求1到一个数n区间内的与k互质的数的个数,那么思路再转换,求互质,可以先求不互质,然后一减不就得到了么?
3. 那么如何求不互质的呢,可以先将k 进行素因子分解,用然后再区间【1,n】 中 ,用 n/素因子 可以得到对应这个素因子的区间内的不互质的个数,然后每个都求一遍,但会有重复的。
下面举个例子:
【1,10】 求关于12的
12 的素因子有 2,3
【1,10】 10/2=5 有5个(2,4,6,8,10)
【1,10】 10 /3=3 有3个(3,6,9)
但是会发现 6重复了
【1,10】 10/(2*3)=1 个-最后结果是 5+3-1=7 个 然后互质的有10 -7=3 个
4. 所以这里有个规律(奇加偶减) 10/2+10/3-10/(2*3)
至于如何求算 有的dfs 和 位运算求解两种把吧
1. 位运算:
用二进制1,0 来表示第几个素因子是否会被用到 如果你求的素因子个数为3 则 i=3时二进制位011 表示第 2 3 个因子被用到
i=1 001 表示只有第3个数被用到
AC1:
#include<bits/stdc++.h>using namespace std;typedef long long ll;ll Sovle(ll n,ll r){ vector<ll> p; // 存放素因子 for(ll 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); ll ans=0; for(ll temp =1;temp<(1<<p.size());temp++) //1左移素因子个数位 { ll multi=1,bits=0; // utli 存放要求的约数 bits是用到的素因子的个数 for(ll i=0;i<p.size();i++) //循环判断每一位是否用到 { if(temp&(1<<i)) //用到 { ++bits; //用到的个数+1 multi*=p[i]; // 乘到约数中 } } ll cur=r/multi; // 求解个数 if(bits&1) ans+=cur; // 奇加偶解 else ans-=cur; } return r-ans;}int main(){ int T,n,cases=0; ll A,B; cin>>T; while(T--) { cin>>A>>B>>n; ll res,ans; ans=Sovle(n,A-1); res=Sovle(n,B); printf("Case #%d: %lld\n",++cases,res-ans); } return 0;}
下面是bfs:
AC2:
#include<bits/stdc++.h>using namespace std;typedef long long ll;vector<ll> fac;void GetFactor(int n){ fac.clear(); for(ll i=2;i*i<=n;i++) { if(n%i==0) { fac.push_back(i); while(n%i==0) n/=i; } } if(n>1) fac.push_back(n);}ll ans;void dfs(int cur,int num,ll mul, ll A){ if(cur==fac.size()) { if(num&1) ans-=A/mul; else ans+=A/mul; return; } dfs(cur+1,num,mul,A); dfs(cur+1,num+1,mul*fac[cur],A);}int main(){ int T,n,cases=0; ll A,B; cin>>T; while(T--) { cin>>A>>B>>n; GetFactor(n); ans=0; dfs(0,0,1,B); ll res=ans; ans=0; dfs(0,0,1,A-1); printf("Case #%d: %lld\n",++cases,res-ans); } return 0;}
- hdu 4135 Co-prime(容互原理 DFS+位运算求解)
- !HDU 4135 Co-prime-容斥原理-(位运算技巧)
- [容斥原理] hdu 4135 Co-prime
- 【HDU】4135 Co-prime 容斥原理
- hdu 4135 Co-prime(容斥原理)
- hdu 4135 Co-prime 容斥原理
- hdu 4135 Co-prime【容斥原理】
- hdu 4135 Co-prime (容斥原理)
- 【容斥原理】HDU 4135 Co-prime
- HDU 4135 Co-prime (容斥原理)
- hdu 4135 Co-prime(容斥原理)
- hdu 4135 Co-prime 容斥原理
- hdu 4135 Co-prime 容斥原理
- HDU 4135 Co-prime(容斥原理)
- HDU 4135 Co-prime(容斥原理)
- HDU 4135 Co-prime 容斥原理
- hdu 4135 Co-prime(容斥原理)
- hdu 4135 Co-prime(容斥原理)
- bootstrap treeview 下拉树 (二) checkBox多选
- Android Studio3.0.0之前首次安装通用配置
- Ubuntu下Lenovo笔记本无法使用无线网卡上网的问题
- 自定义Tabbar
- 浅谈 IIC I2C 总线协议
- hdu 4135 Co-prime(容互原理 DFS+位运算求解)
- 梯度下降算法中的Adagrad和Adadelta
- DeepNet深度学习框架的使用
- 数据结构_序列_字符串
- JavaScript~ajax~分页
- 通过pip下载python相关模块的方法
- URL 长链地址转短链 URL地址
- Android 7.0 静默安装
- 何恺明经典去雾算法