Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5239 Accepted Submission(s): 2093
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 <= 10
15) and (1 <=N <= 10
9).
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: 10HintIn the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
Source
题意:
求出a-b中与n互质的数量。
POINT:
正难则反,求出a-b中不与n互质的数量。
先把n分解质因数,然后求出a-b中与这些质因数成倍数关系的数量。利用容斥原理。
但是我直接在b-(a-1)中找,无限WA.网上的题解是找出(1-b)的数量,在减去(1-a-1)的数量。不知道我这个为什么不行,也比对很多数据,都是一样的,除了A>B的情况,但是题目已经给出A<=B了呀。很奇怪。
void dfs(int ceng,int nowi,LL now)
{
if(ceng==cnt+1) return;
for(int i=nowi+1;i<=cnt;i++)
{
LL d=gcd(now,p[i]);
LL sum=now/d*p[i];
// if(sum>b) return;
if(ceng&1)
{
ans+=b/sum-(a-1)/sum;
}
else
ans-=b/sum-(a-1)/sum;
dfs(ceng+1,i,sum);
}
}
没什么区别,就是找出(1-b)的数量,在减去(1-a-1)的数量。
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
#define LL long long
LL a,b,m;
LL p[1000000];
int cnt;
LL ans;
LL anss;
LL gcd(LL A,LL B)
{
if(A<B) swap(A, B);
return B==0?A:gcd(B,A%B);
}
void prime()
{
cnt=0;
memset(p,0,sizeof p);
for(LL i=2;i*i<=m;i++)
{
if(m%i==0)
{
p[++cnt]=i;
}
while(m%i==0) m/=i;
}
if(m>1)
p[++cnt]=m;
}
void dfs(int ceng,int nowi,LL now)
{
if(ceng==cnt+1) return;
for(int i=nowi+1;i<=cnt;i++)
{
LL d=gcd(now,p[i]);
LL sum=now/d*p[i];
// if(sum>b) return;
if(ceng&1)
{
ans+=b/sum;
}
else
ans-=b/sum;
dfs(ceng+1,i,sum);
}
}
void ddfs(int ceng,int nowi,LL now)
{
if(ceng==cnt+1) return;
for(int i=nowi+1;i<=cnt;i++)
{
LL d=gcd(now,p[i]);
LL sum=now/d*p[i];
// if(sum>b) return;
if(ceng&1)
{
anss+=(a-1)/sum;
}
else
anss-=(a-1)/sum;
ddfs(ceng+1,i,sum);
}
}
int main()
{
int T;
scanf("%d",&T);
int k=0;
while(T--)
{
ans=0;
anss=0;
scanf("%lld %lld %lld",&a,&b,&m);
prime();
dfs(1,0,1);
ddfs(1,0,1);
ans=(b-a+1)-(ans-anss);
printf("Case #%d: %lld\n",++k,ans);
}
}