題解報告:hdu 4135 Co-prime(容斥定理入門)
阿新 • • 發佈:2018-10-19
分解 容斥 ret amp eve 素因子 nbsp desc 使用
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.
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).
2
1 10 2
3 15 5
AC代碼:
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
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
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互質的數的個數,我們可以從其對立面來考慮:分別求區間[1,A-1]、區間[1,B]中與N不互質的數的個數為num1、num2,那麽區間[A,B]與N互質的數的個數就有(B-num2)-(A-1-num1)。怎麽求區間與N不互質的數的個數呢?先分解出N的所有素因子,因為任何一個不小於2的數都能表示成若幹個素數的乘積,然後用其素因子來篩選計算出區間中與N不互質的數的個數即X/p_i(p_i為素因子),這裏要用容斥定理,不重復計數,也沒有遺漏,公式:1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 int t,cnt,prime[15];LL a,b,n; 5 LL solve(LL x){//求與n不互質的總個數 6 int num;LL ans=0,tp; 7 for(int i=1;i<(1<<cnt);++i){//用二進制來表示每個質因子是否被使用,即有2^cnt-1種可能,此時cnt較小,題目中1e9最多也就8個素因子,二進制優化 8 tp=1,num=0; 9 for(int j=0;j<cnt;++j) 10 if(i&(1<<j))num++,tp*=prime[j];//表示選擇哪幾個素因子 11 if(num&1)ans+=x/tp;//奇加 12 else ans-=x/tp;//偶減 13 } 14 return x-ans; 15 } 16 int main(){ 17 while(~scanf("%d",&t)){ 18 for(int i=1;i<=t;++i){ 19 scanf("%lld%lld%lld",&a,&b,&n);cnt=0; 20 for(LL j=2;j*j<=n;++j){//求出n內的所有質因子 21 if(n%j==0){ 22 prime[cnt++]=j; 23 while(n%j==0)n/=j; 24 } 25 } 26 if(n>1)prime[cnt++]=n; 27 printf("Case #%d: %lld\n",i,solve(b)-solve(a-1));//區間差 28 } 29 } 30 return 0; 31 }
題解報告:hdu 4135 Co-prime(容斥定理入門)