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

 

posted @ 2013-09-27 22:11  线性无关  阅读(179)  评论(0)    收藏  举报