[原创]HDU 4135 Co-prime [容斥定理]【数论】

2016-08-11 19:59:34 Tabris_ 阅读数:238


博客爬取于2020-06-14 22:43:53
以下为正文

版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/52186000


题目连接: 传送阵
------------------------------.
Co-prime

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3902 Accepted Submission(s): 1536

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

------------------------------------.
题目大意: 就是求a~b区间内与n互质的数的个数

解题思路:与n互质的数的个数也就是gcd(x,n)==1.但是数据量非常大 所以暴力不可解
于是换个思路 就是求gcd(x,n)!=1的数的个数 然后区间总数减一下 就能得到结果
gcd(x,n)!=1就简单了

只要求出[1~a-1][1~b]这两个区间内的与n有约数(非1)的数的个数
想到把n质因子分解 然后容斥定理求解即可

附本题代码
----------------------------------.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# include <stdio.h>
# include <vector>
# include <iostream>
using namespace std;
# define LL long long int
# define pb push_back
LL solve (LL n, LL r)
{
vector<int> p;
for (int i=2; i*i<=n; ++i)
if (n % i == 0)
{
p.pb (i);
while (n % i == 0)
n /= i;
}
if (n > 1) p.pb (n);

LL sum = 0;
for (int msk=1; msk<(1<<p.size()); ++msk)
{
LL mult = 1,
bits = 0;
for (int i=0; i<(LL)p.size(); ++i)
if (msk & (1<<i))
{
++bits;
mult *= p[i];
}

LL cur = r / mult;
if (bits % 2 == 1)
sum += cur;
else
sum -= cur;
}

return r - sum;
}
int main()
{
int _,p=0;
scanf("%d",&_);
while(_--)
{
LL a,b,n;
scanf("%I64d%I64d%I64d",&a,&b,&n);
LL sum = solve(n,b)-solve(n,a-1);
printf("Case #%d: %I64d\n",++p,sum);
}
return 0;
}