Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8484 Accepted Submission(s): 3375
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}.
ac:
求(a,b)中n的互质转化为求: n关于 (1,b) - (1,a-1) 互质
互质=总数-因子数
我们需要求(1,m)中n的因子个数
先求n的素因子
再用依次m/(n的素因子),再用容斥
比如(1,15) 中6的素因子
6的素因子:
2,3
总素因子=15/2+15/3-15/(2*3)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll s[1020],k;
void prime(long long m)//求一个数的素因子
{
ll i;
k=0;
for(i=2;i*i<=m;i++)
{
if(m%i==0)
{
s[k++]=i;
while(m%i==0)
m/=i;
}
}
if(m>1)//别忘记了
s[k++]=m;
}
ll quc(long long m)//队列数组实现容斥原理
{
ll que[10020],i,j,t=0,sum=0,z;
que[t++]=-1;
for(i=0;i<k;i++)
{
z=t;
for(j=0;j<z;j++)
{
que[t++]=que[j]*s[i]*(-1);
}
}
for(i=1;i<t;i++)
sum+=m/que[i];
return sum;
}
int main()
{
ll n;
int cas=1;
scanf("%lld",&n);
while(n--)
{
ll a,b,m,sum;
scanf("%lld %lld %lld",&a,&b,&m);
prime(m);
sum=b-quc(b)-(a-1)+quc(a-1);
printf("Case #%d: %lld\n",cas++,sum);
}
}