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}.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
/*
题意:问[A,B]中与N,互质的个数
思路:
脑子直接就考虑到欧拉函数的定义,但是好像不太对,考虑欧拉函数的容斥定理
考虑N的因子,如果[1,B]区间的数是N素因子的倍数,肯定是不可以的,所以想到加法原理,但是会有重复,核心
就是容斥原理
比如[1,20] N=6,
我们需要考虑 2的倍数,3的倍数,6的倍数
++--就可以得出来了
*/
ll A,B,N;
//素数分解
vector<ll> vec;
void init(){
vec.clear();
ll m=sqrt(N+0.5),n=N;
for(ll i=2;i<=m;i++){
if(n%i==0){
vec.push_back(i);
while(n%i==0)n/=i;
}
}
if(n>1) vec.push_back(n);
}
//容斥定理
//好长时间没用,都忘了这个枚举的方法了
ll get_ans(ll x){
ll ans=x;
int sz=vec.size();
for(ll i=1;i<(1ll<<sz);i++){
ll tmp=1;
int cnt=0;
for(int j=0;j<sz;j++){
if((1ll<<j)&i){
tmp*=vec[j];
cnt++;
}
}
if(cnt&1) ans-=x/tmp;
else ans+=x/tmp;
}
return ans;
}
int main(){
int T;
scanf("%d",&T);
rep(kase,1,T+1){
scanf("%lld %lld %lld",&A,&B,&N);
init();
ll ans_A=get_ans(A-1),ans_B=get_ans(B);
printf("Case #%d: %lld\n",kase,ans_B-ans_A);
}
return 0;
}