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