HDU 4135 Co-prime(容斥原理 + 基础数论)
2016-08-08 11:01
483 查看
传送门
Total Submission(s): 3695 Accepted Submission(s): 1461
[align=left]Problem Description[/align] 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.
[align=left]Input[/align] 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).
[align=left]Output[/align] 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.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
HintIn the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
[align=left]Source[/align]
题目大意:
给一个区间 [a,b][a,b] 求这个区间中 与 nn 互素的个数。
解题思路:
这个问题可以转化为求 [1,b][1,b] 区间中与 nn 互素的个数 ans1ans1 减去 [1,a−1][1,a-1] 区间中与 nn 互素的个
数 ans2ans2 ,那么 [1,x][1,x] 区间中与 nn 互素的个数怎么求呢,可以先将 nn 进行素因子分解,然后用区间
xx 除以 素因子,就得到了与 nn 的 约数是那个素因子的个数,然后每次这样求一遍,但是发现有重
复的:举个例子 [1,10][1,10] 区间中与 66 互素的个数,应该是 10−(10/2+10/3)10-(10/2+10/3) 但是这样多减去
了他们的最小公倍数 66 的情况,所以在加上 10/610/6 也就是:
10−(10/2+10/3−10/6)=310-(10/2+10/3-10/6)=3
这就用到了容斥原理,知道了这个,题目也就可以做了,先进行素因子分解,然后二进制枚举子集
进行容斥原理(奇加偶减):
MyMy Code:Code:
Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3695 Accepted Submission(s): 1461
[align=left]Problem Description[/align] 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.
[align=left]Input[/align] 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).
[align=left]Output[/align] 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.
[align=left]Sample Input[/align]
2 1 10 2 3 15 5
[align=left]Sample Output[/align]
Case #1: 5 Case #2: 10
HintIn the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
[align=left]Source[/align]
题目大意:
给一个区间 [a,b][a,b] 求这个区间中 与 nn 互素的个数。
解题思路:
这个问题可以转化为求 [1,b][1,b] 区间中与 nn 互素的个数 ans1ans1 减去 [1,a−1][1,a-1] 区间中与 nn 互素的个
数 ans2ans2 ,那么 [1,x][1,x] 区间中与 nn 互素的个数怎么求呢,可以先将 nn 进行素因子分解,然后用区间
xx 除以 素因子,就得到了与 nn 的 约数是那个素因子的个数,然后每次这样求一遍,但是发现有重
复的:举个例子 [1,10][1,10] 区间中与 66 互素的个数,应该是 10−(10/2+10/3)10-(10/2+10/3) 但是这样多减去
了他们的最小公倍数 66 的情况,所以在加上 10/610/6 也就是:
10−(10/2+10/3−10/6)=310-(10/2+10/3-10/6)=3
这就用到了容斥原理,知道了这个,题目也就可以做了,先进行素因子分解,然后二进制枚举子集
进行容斥原理(奇加偶减):
MyMy Code:Code:
/** 2016 - 08 - 08 上午 Author: ITAK Motto: 今日的我要超越昨日的我,明日的我要胜过今日的我, 以创作出更好的代码为目标,不断地超越自己。 **/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <set> using namespace std; typedef long long LL; typedef unsigned long long ULL; const int INF = 1e9+5; const int MAXN = 1e6+5; const int MOD = 1e9+7; const double eps = 1e-7; const double PI = acos(-1); using namespace std; bool prime[MAXN]; LL p[MAXN]; int k; ///素数筛选 void isprime() { k = 0; memset(prime, 0, sizeof(prime)); for(LL i=2; i<MAXN; i++) { if(!prime[i]) { p[k++] = i; for(LL j=i*i; j<MAXN; j+=i) prime[j] = 1; } } } LL fac[MAXN/100]; int cnt = 0; void Dec(LL x) { cnt = 0; for(int i=0; p[i]*p[i]<=x&&i<k; i++) { if(x%p[i]==0) { fac[cnt++] = p[i]; while(x%p[i]==0) x /= p[i]; } } if(x > 1) fac[cnt++] = x; } LL Solve(LL x) { LL ret = 0; for(LL i=1; i<(1LL<<cnt); i++) { int sum = 0, tmp = 1; for(int j=0; j<cnt; j++) { if(i & (1LL<<j)) { sum++; tmp *= fac[j]; } } if(sum & 1) ret += x/tmp; else ret -= x/tmp; } return ret; } int main() { isprime(); int T; LL N, A, B; scanf("%d",&T); for(int cas=1; cas<=T; cas++) { scanf("%I64d%I64d%I64d",&A,&B,&N); Dec(N); printf("Case #%d: %I64d\n",cas,B-Solve(B)-A+1+Solve(A-1)); } return 0; }
相关文章推荐
- HDU 4135 Co-prime(容斥+数论)
- HDU 5072 Coprime(数论+容斥原理)
- 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(容斥原理)
- hdu 4135 Co-prime 容斥原理