Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3313 Accepted Submission(s): 1286
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 <= 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
Recommend
思路:素数打表+容斥原理;
因为要求在[n,m]中与互质的数的个数。
先打表求素数,然后分解k,求出k由哪些素数组成,然后我们可以用容斥求出[n,m]中与k不互质的数,然后区间长度减下即可;
每个数的质因数个数不会超过20个。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdlib.h> 5 #include<string.h> 6 #include<vector> 7 #include<queue> 8 #include<stack> 9 using namespace std; 10 long long gcd(long long n,long long m); 11 bool prime[100005]; 12 int ans[100005]; 13 int bns[100005]; 14 int dd[100005]; 15 typedef long long LL; 16 int main(void) 17 { 18 int i,j,k; 19 scanf("%d",&k); 20 int s; 21 LL n,m,x; 22 for(i=2; i<=1000; i++) 23 { 24 if(!prime[i]) 25 { 26 for(j=i; i*j<=100000; j++) 27 { 28 prime[i*j]=true; 29 } 30 } 31 } 32 int cnt=0; 33 for(i=2; i<=100000; i++) 34 { 35 if(!prime[i]) 36 { 37 ans[cnt++]=i; 38 } 39 } 40 for(s=1; s<=k; s++) 41 { 42 int uu=0; 43 memset(dd,0,sizeof(dd)); 44 scanf("%lld %lld %lld",&n,&m,&x); 45 while(x>=1&&uu<cnt) 46 { 47 if(x%ans[uu]==0) 48 { 49 dd[ans[uu]]=1; 50 x/=ans[uu]; 51 } 52 else 53 { 54 uu++; 55 } 56 } 57 int qq=0; 58 for(i=2; i<=100000; i++) 59 { 60 if(dd[i]) 61 { 62 bns[qq++]=i; 63 } 64 } 65 if(x!=1) 66 bns[qq++]=x; 67 n--; 68 69 LL nn=0; 70 LL mm=0; 71 for(i=1; i<=(1<<qq)-1; i++) 72 { 73 int xx=0; LL sum=1; 74 int flag=0; 75 for(j=0; j<qq; j++) 76 { 77 if(i&(1<<j)) 78 { 79 xx++; 80 LL cc=gcd(sum,bns[j]); 81 sum=sum/cc*bns[j]; 82 if(sum>m) 83 { 84 flag=1; 85 break; 86 } 87 } 88 } 89 if(flag) 90 continue; 91 else 92 { 93 if(xx%2==0) 94 { 95 nn-=n/sum; 96 mm-=m/sum; 97 } 98 else 99 { 100 nn+=n/sum; 101 mm+=m/sum; 102 } 103 } 104 }m-=mm;n-=nn; 105 printf("Case #%d: ",s); 106 printf("%lld ",m-n); 107 } 108 return 0; 109 } 110 long long gcd(long long n,long long m) 111 { 112 if(m==0) 113 return n; 114 else if(n%m==0) 115 return m; 116 else return gcd(m,n%m); 117 }