数论HDU4135:Co-prime

Posted 听风不成泣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论HDU4135:Co-prime相关的知识,希望对你有一定的参考价值。

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 <= 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}. 
         
 

题目大意:

给一个区间[a,b],从区间[a,b]中找出共有多少个数是与n互质的。

 

思路:

欧拉函数得到的是小于n与n互质的个数,这里是个区间。由于区间较大,不可能对[a,b]进行遍历,

考虑计算区间[1,a-1]中与n互质的个数num1,[1,b]中与n互质的个数num2,最终结果就是两者

相减的结果。

现在考虑如何计算区间[1,m]中n互质的个数num,num等于 (m - 与n不互质的个数)。

与n不互质的数就是[1,m]中n的素因子的倍数。

例如m = 12,n = 30的情况。

30的素因子数为2、3、5。

[1,12]中含有2的倍数的有:(2、4、6、8、10、12) = n/2 = 6个

[1,12]中含有3的倍数的有:(3、6、9、12) = n/3 = 4个

[1,12]中含有5的倍数的有:(5、10) = n/5 = 2个

与n不互质的数个数就是上边三个集合取并集的部分。这里用到了容斥定理,我用的增长的队列数组

来实现容斥定理,具体参考代码。

 

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #define ll __int64
 4 using namespace std;
 5 const int maxn = 1e5+50;
 6 ll factor[105],s[maxn],num;
 7 void getphi(ll x){
 8     num = 0;
 9     for(ll i = 2; i*i <= x; i++)
10     {
11         if(x % i == 0)
12         {
13             while(x % i == 0)
14             {
15                 x /= i;
16             }
17             factor[num++]=i;
18         }
19     }
20     if(x != 1)
21         factor[num++]=x;
22 
23 }
24 ll solve(ll n)
25 {
26     ll k,cnt,ans;
27     cnt=ans=0;
28     s[cnt++]=-1;
29     for(ll i=0;i<num;i++)
30     {
31         k=cnt;
32         for(ll j=0;j<k;j++)
33         {
34             s[cnt++]=-1*s[j]*factor[i];
35         }
36     }
37     for(ll i=1;i<cnt;i++)
38     {
39         ans+=n/s[i];
40     }
41     return ans;
42 }
43 int main()
44 {
45     int T;
46     scanf("%d",&T);
47     for(int i=1;i<=T;i++)
48     {
49         ll x,y,n;
50         scanf("%I64d%I64d%I64d",&x,&y,&n);
51         getphi(n);
52         ll a=y-solve(y);
53         ll b=x-1-solve(x-1);
54         ll ans=a-b;
55         printf("Case #%d: %I64d\n",i,ans);
56     }
57 
58     return 0;
59 }
View Code

 

 

以上是关于数论HDU4135:Co-prime的主要内容,如果未能解决你的问题,请参考以下文章

HDU4135 Co-prime 容斥原理

题解报告:hdu 4135 Co-prime(容斥定理入门)

hdu4135 Co-prime容斥原理

hdu4135Co-prime 容斥原理水题

HDU 4135 Co-prime (容斥+分解质因子)

hdu 4135 Co-prime (素数打表+容斥原理)