Co-prime(容斥原理+筛一个数的素因子)
Co-prime
HDU - 4135
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.
InputThe 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).OutputFor 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互素的数的个数。
题解:
先找出n的素因子,比如n=30,那么找到30的素因子2 3 5,然后在区间[a,b]内用容斥原理找到2,3,5的倍数的个数ans,然后用区间长度减掉ans。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 typedef long long ll;
7 const ll maxn=1e6+10;
8 ll n,cnt,ans;
9 ll prime[maxn];
10 ll l,r;
11 ll gcd(ll a,ll b)
12 {
13 if(b==0)
14 return a;
15 else
16 return gcd(b,a%b);
17 }
18 ll Lcm(ll a,ll b)
19 {
20 return a*b/gcd(a,b);
21 }
22 ll get_prime(ll x)//如何找到x的素因子
23 {
24 for(ll i=2;i*i<=x;i++)
25 {
26 if(x%i)
27 continue;
28 while(x%i==0)
29 x/=i;
30 prime[cnt++]=i;
31 }
32 if(x!=1) //如果x本身就是素数
33 prime[cnt++]=x;
34 }
35 int casen;
36 void dfs(ll m,ll th,ll now,ll step)
37 {
38
39 ll lcm=Lcm(prime[th],now);
40 if(step&1)
41 {
42 ans+=m/lcm;
43 }
44 else
45 {
46 ans-=m/lcm;
47 }
48 for(ll i=th+1;i<cnt;i++)
49 dfs(m,i,lcm,step+1);
50 }
51 int main()
52 {
53 scanf("%d",&casen);
54 int ca=1;
55 while(casen--)
56 {
57 ans=0;
58 cnt=0;
59 scanf("%lld%lld%lld",&l,&r,&n);
60 get_prime(n);
61
62 for(ll i=0;i<cnt;i++)
63 dfs(l-1,i,prime[i],1);
64 ll le=l-1-ans;
65 //cout<<le<<endl;
66 ans=0;
67 for(ll i=0;i<cnt;i++)
68 dfs(r,i,prime[i],1);
69 ll ri=r-ans;
70 // cout<<ri<<endl;
71 printf("Case #%d: %lld\n",ca++,ri-le);
72 }
73 }