# HDOJ4135 Co-prime --- 容斥原理

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

（求1....n中m的倍数的个数，n / m即可求出）

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
ll A,B,N;
ll factor[2000];// 存储质因数
ll num;// 质因数个数

// 计算1..n之间有多少数与a不互质
ll fun(ll n,ll a) {
if(n == 0) return 0;
num = 0;
// 对a分解质因数
ll temp = a;
for(ll i = 2;i*i <= temp;i++) {
// 找到质因数
if(temp % i == 0) {
factor[num++] = i;
}
while(temp % i == 0) temp /= i;
}
if(temp > 1) {
factor[num++] = temp;
}
// 容斥原理
ll cnt = 0;
bool flag;// 标记正负号
// 在容斥公式中遍历所有数据项，如A+B+C-AB-AC-BC+ABC中遍历每项
for(ll i = 1;i < (ll)(1<<num);i++) {
flag = false;// 负号
ll t = 1;
// 在A,B,C中遍历存在的项
for(ll j = 0;j < num;j++) {
// 判断i的二进制中第j位是否存在
if(i & (ll)(1<<j)) {
t *= factor[j];
if(flag == true)
flag = false;
else
flag = true;
}
}
if(flag) {
cnt += n / t;
} else {
cnt -= n / t;
}

}

return cnt;
}

int main()
{
int Case = 1;
int t;
scanf("%d",&t);
while(t--) {
scanf("%lld%lld%lld",&A,&B,&N);
printf("Case #%d: %lld\n",Case++,(B-A+1) - (fun(B,N)-fun(A-1,N)));
}

return 0;
} 

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120