【数论】HDU4135:Co-prime
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: 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}.
题目大意:
给一个区间[a,b],从区间[a,b]中找出共有多少个数是与n互质的。
思路:
欧拉函数得到的是小于n与n互质的个数,这里是个区间。由于区间较大,不可能对[a,b]进行遍历,
考虑计算区间[1,a-1]中与n互质的个数num1,[1,b]中与n互质的个数num2,最终结果就是两者
相减的结果。
现在考虑如何计算区间[1,m]中n互质的个数num,num等于 (m - 与n不互质的个数)。
与n不互质的数就是[1,m]中n的素因子的倍数。
例如m = 12,n = 30的情况。
30的素因子数为2、3、5。
[1,12]中含有2的倍数的有:(2、4、6、8、10、12) = n/2 = 6个
[1,12]中含有3的倍数的有:(3、6、9、12) = n/3 = 4个
[1,12]中含有5的倍数的有:(5、10) = n/5 = 2个
与n不互质的数个数就是上边三个集合取并集的部分。这里用到了容斥定理,我用的增长的队列数组
来实现容斥定理,具体参考代码。
1 #include <iostream> 2 #include <cstdio> 3 #define ll __int64 4 using namespace std; 5 const int maxn = 1e5+50; 6 ll factor[105],s[maxn],num; 7 void getphi(ll x){ 8 num = 0; 9 for(ll i = 2; i*i <= x; i++) 10 { 11 if(x % i == 0) 12 { 13 while(x % i == 0) 14 { 15 x /= i; 16 } 17 factor[num++]=i; 18 } 19 } 20 if(x != 1) 21 factor[num++]=x; 22 23 } 24 ll solve(ll n) 25 { 26 ll k,cnt,ans; 27 cnt=ans=0; 28 s[cnt++]=-1; 29 for(ll i=0;i<num;i++) 30 { 31 k=cnt; 32 for(ll j=0;j<k;j++) 33 { 34 s[cnt++]=-1*s[j]*factor[i]; 35 } 36 } 37 for(ll i=1;i<cnt;i++) 38 { 39 ans+=n/s[i]; 40 } 41 return ans; 42 } 43 int main() 44 { 45 int T; 46 scanf("%d",&T); 47 for(int i=1;i<=T;i++) 48 { 49 ll x,y,n; 50 scanf("%I64d%I64d%I64d",&x,&y,&n); 51 getphi(n); 52 ll a=y-solve(y); 53 ll b=x-1-solve(x-1); 54 ll ans=a-b; 55 printf("Case #%d: %I64d\n",i,ans); 56 } 57 58 return 0; 59 }