Coprime HDU - 3388


Coprime HDU - 3388 


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



t題意:  求與n,m  互質的第 k 個數。


思路:   容斥+二分   由於  m,n  很大直接枚舉  出第 K 個不現實,那麼我們考慮先找出 小於 x 的與  n,m 不互質的數 sn,然後互質的數就是   x- sn ;

與 n,m 不互質的數就是  gcd( n,i )!=1  gcd( m,i ) !=1;其實就是容斥裏面的常規題型了(求小於 x 內有多少個數與 x 互質) 

具體 思路:  找出 n,m  的質因子,然後去重(  可以用  set ),用容斥求解。

注意  二分  上限取值  ,小了會WA.


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<algorithm>
#define maxn 10010
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MOD 1000000007
#define ll long long
using namespace std;


int m,n,k;
set<int>s;
int fac[500];
int len;
void Get(int a)
{
    for(int i=2;i*i<=a;i++)
    {
        if(a%i==0)
        {
            s.insert(i);    a/=i;
            while(a%i==0)   a/=i;
        }
    }
    if(a>1)  s.insert(a);
}
void Change()
{
    len=0;
    while(!s.empty())
    {
        fac[len++]=*s.begin();
        s.erase(s.begin());
    }

}
ll solve(ll tem,ll t)
{
    ll sum=0;
    for(int i=t;i<len;i++)
    {
        sum+=tem/fac[i]-solve(tem/fac[i],i+1);
    }
    return sum;
}
int main()
{

    int T;
    int kase=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&m,&n,&k);
        printf("Case %d: ",kase++);
        if(k==1)  { puts("1"); continue; }
        Get(m);Get(n);Change();
        ll l=0,r=0x3f3f3f3ff;
        while(r>=l)
        {
            ll mid=(r+l)/2;
            if(k>mid-solve(mid,0))
                l=mid+1;
            else r=mid-1;
        }
        printf("%lld\n",l);
    }
    return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章