hdu4135题解 容斥
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.
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 <= 10
15) and (1 <=N <= 10
9).
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: 10HintIn the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.首先感谢ACM不懈的追求大神的博客,本题解的代码是在该大神的题解的基础上完成的:http://www.cnblogs.com/jiangjing/archive/2013/06/03/3115470.html题目大意:给定整数N,求出多少a到b区间(包含a,b,以下关于区间的描述都包括边界),有多少个数字和N互质。思路:因为数量巨大,如果用辗转相除法会造成超时。我们应该回归互质的定义:两个数字的最大公约数为1称之为互质。故两数互质和两数不互质(印象里面好像叫做互余吧)互为独立事件(这说话的腔调真是受不了。。。)。总而言之,如果我们能求出该区间有多少个数字和N不互质就好了。那么怎么求不互质的个数呢?(设问既有过渡的功能也有引起读者兴趣的作用,哈哈,好了不扯了),好的,我们先把问题改成求1到b区间和N不互质的个数,我们要先找出N的所有质因数,并求出这些质因数相乘可以组合成哪些数字,并求出b除以这些数字的和(不保留小数部分),并且因为有重叠的部分,我们这时候就需要用到互斥定理,例如:b=10,N=48,那么质因数为2,3。这些质因数相乘的组合有:1,2,3,6(可以选择只要其中一个数甚至不选),这时候用互斥定理,答案就是:int(10/-1)+int(10/2)+int(10/3)+int(10/-6),同理,我们可以求出1到a-1区间和N不互质的个数。最难的骨头啃下来了,我们可以求出答案,假设1到b区间和N不互质的个数为f(b),假设1到a-1区间和N不互质的个数为f(a-1),那么题目的答案就是b-f(b)-(a-1-f(a-1)),好的,此处应该有掌声.//hud 4135 #include<cstdio> #include<iostream> #include<vector> #define maxn 100005 using namespace std; vector <__int64> factor; __int64 p[maxn]; int len_p; void getfactor(__int64 x) { factor.clear(); for(__int64 i = 2; i * i <= x; i ++) { if(x % i == 0) { factor.push_back(i); while(x % i == 0) { x /= i; } } } if(x > 1) { factor.push_back(x); } } void getp() { p[0] = -1; len_p = 1; int len_factor = factor.size(); for(__int64 i = 0; i < len_factor; i ++) { int k = len_p; for(__int64 j = 0; j < k; j ++) { p[len_p ++] = factor[i] * p[j] * (-1); } } } __int64 f(__int64 x) { __int64 ans = 0; for(int i = 1; i < len_p; i ++) { ans += (x / p[i]); } return ans; } int main() { int d,cas = 1; cin >> d; while(d --) { __int64 a, b, n; scanf("%I64d%I64d%I64d", &a, &b, &n); getfactor(n); printf("Case #%d: ", cas ++); getp(); cout << b - f(b) - (a - 1 - f(a - 1)) << endl; } return 0; } /* 2 1 10 2 3 15 5 ans:5 10 */
本文来自博客园,作者:MrYu4,转载请注明原文链接:https://www.cnblogs.com/MrYU4/p/15778912.html