题目:
A - Co-prime
Time Limit: 1000 MS Memory Limit: 32768 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
[Submit] [Status]
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}.
题意:
a到b之间有几个与n互质的数;
思路:
暴力肯定超时,所以用容斥定理;
a到b之间有几个互质的数,可以理解为求1~b之间与n互质的数的个数-1~a-1之间与n的互质的数的个数,求与n互质可以理解为求总个数减去不互质的个数,不互质怎么求呢,可以把n分解质因数,那么b里是n的质因数的倍数的一定不与n互质,所以可以把b里每个n的质因数的倍数都求出来,然后减去重复的,结果为:b/2+b/3+b/5-b/(2*3)-b/(2*5)-b/(3*5)+b/(2*3*5),容斥定理,奇加偶减;
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1e7;
long long int a[maxn];
long long int num=0;
void init(long long int n)
{
num=0;
for(int j=2; j<=sqrt(n); j++)
{
if(n%j==0)
{
a[num++]=j;
while(n%j==0)
n=n/j;
}
}
if(n>1)
{
a[num++]=n;
}
}
long long rongchi(long long m)
{
long long int que[10000],i,j,k,sum=0;
long long int t=0;
que[t++]=-1;
for(i=0; i<num; i++)
{
k=t;
for(j=0; j<k; j++)
{
que[t++]=que[j]*a[i]*(-1);
}
}
for(i=1; i<t; i++)
sum=sum+m/que[i];
return sum;
}
int main()
{
int T;
scanf("%d",&T);
int p=0;
while(T--)
{
p++;
long long int a,b,n;
scanf("%lld%lld%lld",&a,&b,&n);
init(n);
long long int ans=(b-rongchi(b))-(a-1-rongchi(a-1));
printf("Case #%d: %lld\n",p,ans);
}
}