Co-prime
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 49 Accepted Submission(s) : 21
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
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: 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}.
Source
The Third Lebanese Collegiate Programming Contest
——————————————————————————————————
题目的意思是给出一段区间求与给出的k互质的数有几个
思路:先把问题转化为前缀和问题,然后算出与k有公因数有多少个,可以先对k分解质
因
数,这样的数的种类肯定不多
然后dfs求每种数的个数,用容斥原理计数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
using namespace std;
#define LL long long
const int inf=0x7fffffff;
LL p[100005];
LL ans,l,r;
int tot;
void dfs(int pos,LL x,int cnt)
{
if(pos>=tot)
{
if(cnt==0)
return;
if(cnt%2)
{
ans+=r/x;
ans-=(l-1)/x;
}
else
{
ans-=r/x;
ans+=(l-1)/x;
}
return;
}
dfs(pos+1,x*p[pos],cnt+1);
dfs(pos+1,x,cnt);
}
int main()
{
int T;
LL k;
scanf("%d",&T);
int q=1;
while(T--)
{
tot=0;
scanf("%lld%lld%lld",&l,&r,&k);
for(LL i=2;i*i<=k;i++)
{
if(k%i==0)
p[tot++]=i;
while(k%i==0) k/=i;
}
if(k>1) p[tot++]=k;
ans=0;
dfs(0,1,0);
ans=r-l+1-ans;
printf("Case #%d: %lld\n",q++,ans);
}
return 0;
}