Coprime

来源:互联网 发布:js图片渐变轮换效果 编辑:程序博客网 时间:2024/05/16 15:38

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

36 9 16 9 26 9 3

Sample Output

Case 1: 1Case 2: 5Case 3: 7

Author

xay@whu

Source

The 5th Guangting Cup Central China Invitational Programming Contest

思路:这题我是用的二分+容斥,令d为一个很大的数字,那么第k个与m和n同时互素的数一定在1~d里面,先判断1~h(h=(1+d)/2)内与m和
n同时互素的有多少个(用容斥定理进行判断),如果大于k就从(h~l)进行判断,如果小于k,就从1~h进行判断;直到等于k,这时候判断h--,直到1~h内与m和n互素的个数为k-1这时候返回h+1;

代码如下:
#include<iostream>#include<algorithm>using namespace std;typedef long long ll;int cnt,p[100];ll relatively_prime(ll m){    ll sum=0;    for(ll i=1;i<(1<<cnt);i++)    {        ll s=1,l=0;        for(int j=0;j<cnt;j++)        {            if(i&(1<<j))            {                l++;                s=s*p[j];            }        }        s=m/s;        if(l%2)        sum=sum-s;        else        sum=sum+s;    }    return m+sum;}//判断(1~m)内互素的个数;ll binary_find(ll l,ll h,ll n){    ll m=(l+h)/2,s;    s=relatively_prime(m);    if(s>n)      return binary_find(l,m,n);    else if(s<n)      return binary_find(m,h,n);    else    {        while(1)        {            m--;            ll t=relatively_prime(m);            if(t!=n)                break;        }        return m+1;    }}//二分;int main(){    ll t,n,m,k,flag,s;    cin>>t;    for(int i=1;i<=t;i++)    {        cin>>n>>m>>k;        cnt=0;        for(int j=2;j*j<=n||j*j<=m;j++)        {            flag=1;            if(n%j==0&&j!=m)            {                flag=0;                p[cnt++]=j;            }            if(m%j==0&&j!=n)            {                if(flag)                p[cnt++]=j;            }             while(n%j==0)                n=n/j;             while(m%j==0)                m=m/j;        }        if(n>1)            p[cnt++]=n;        if(m>1&&m!=n)            p[cnt++]=m;        sort(p,p+cnt);        s=binary_find(1,1000000000000000,k);        cout<<"Case "<<i<<": "<<s<<endl;    }    return 0;}