HDU 3388 二分+容斥
Coprime
Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 604    Accepted Submission(s): 149 
Problem Description
Please write a program to calculate the k-th positive integer that is coprime with m and n simultaneously. A is coprime with B when their greatest common divisor is 1.
Input
The first line contains one integer T representing the number of test cases. For each case, there's one line containing three integers m, n and k (0 < m, n, k <= 10^9).
Output
For each test case, in one line print the case number and the k-th positive integer that is coprime with m and n. Please follow the format of the sample output.
Sample Input
3
6 9 1
6 9 2
6 9 3
Sample Output
Case 1: 1
Case 2: 5
Case 3: 7
题目给定三个数,n,m,k,要求输出与n,m互素的第k个数。
解题思路:首先打素数表,将n,m进行质因数分解,去掉两个之间共同的质因子,然后二分答案,判断某一个数是所需的答案。
代码:
#include<iostream> #include<stdio.h> #include<string> #include<string.h> #include<algorithm> #include<vector> #include<stdlib.h> using namespace std; typedef __int64 ll; ll isprime[1000100],indexx=0,prime[111111],factor[1000],cnt; void getprime() { memset(isprime,1,sizeof(isprime)); isprime[1]=0; ll i,j; for(i=2;i<=1000000;i++) { if(isprime[i])prime[indexx++]=i; for(j=0;j<indexx&&i*prime[j]<=1000000;j++) { isprime[i*prime[j]]=0; if(i%prime[j]==0)break; } } // cout<<indexx<<endl; } void getfactor(ll x) { ll i,j,k; for(i=0;i<indexx&&prime[i]*prime[i]<=x;i++) { if(x%prime[i]==0) { factor[cnt++]=prime[i]; while(x%prime[i]==0)x/=prime[i]; } } if(x>1)factor[cnt++]=x; } ll fun(ll x) { ll ans=x,i,j,k,m; for(i=1;i<(1<<cnt);i++) { k=0; m=1; for(j=0;j<cnt;j++) { if((i>>j)&1) { m*=factor[j]; k++; } } m=x/m; if(k%2==1)ans-=m; else ans+=m; } return ans; } int main() { getprime(); ll i,j,k,m,n,p,q,T,t; scanf("%I64d",&T); for(t=1;t<=T;t++) { scanf("%I64d%I64d%I64d",&n,&m,&k); cnt=0; getfactor(n); getfactor(m); sort(factor,factor+cnt); cnt=unique(factor,factor+cnt)-factor; // cout<<cnt<<endl; ll l=1,r=1e17,mid; while(l<r) { mid=(l+r)>>1; //cout<<mid<<endl; if(fun(mid)<k)l=mid+1; else r=mid; } printf("Case %I64d: %I64d\n",t,l); // cout<<fun(5)<<endl; } return 0; }
                    
                
                
            
        
浙公网安备 33010602011771号