G. List Of Integers
time limit per test 5seconds
memory limit per test 256megabytes
Let's denote asL(x, p) an infinitesequence of integers y such that gcd(p, y) = 1 and y > x (where gcd is the greatestcommon divisor of two integer numbers), sorted in ascending order. The elementsofL(x, p) are 1-indexed; forexample, 9,13 and 15 are the first,the second and the third elements of L(7, 22), respectively.
You have to processt queries. Eachquery is denoted by three integers x,p and k, and the answerto this query is k-th element of L(x, p).
Input
The first line contains one integert (1 ≤ t ≤ 30000) — the numberof queries to process.
Thent lines follow. i-th linecontains three integers x,p and k for i-th query (1 ≤ x, p, k ≤ 106).
Output
Printt integers, where i-th integer isthe answer to i-th query.
Examples
Input
3
7 22 1
7 22 2
7 22 3
Output
9
13
15
Input
5
42 42 42
43 43 43
44 44 44
45 45 45
46 46 46
Output
187
87
139
128
141
【题意】
求大于x且与p互质的第k大的数。
【思路】
对于任意的x,我们可以用快速容斥求出【1,x】中与p互质的数的个数。
那么我们先算【1,x】中与p互质的数的个数num,那么我们要输出的便是第(num+k)个与p互质的数。
由前面可知,我们利用容斥然后二分即可。
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef long long ll;
const int maxn = 200005;
const ll mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
ll x,p,k;
vector<ll>vec;
ll cal(ll x)
{
ll ans=0;
int num=vec.size();
for(int i=0;i<(1<<num);i++)
{
ll now=1,flag=1;
for(int j=0;j<num;j++)
{
if((i>>j)&1)
{
now*=vec[j];
flag*=-1;
}
}
ans+=flag*(x/now);
}
return ans;
}
int main()
{
rush()
{
scanf("%lld%lld%lld",&x,&p,&k);
vec.clear();
for(ll i=2;i*i<=p;i++)
{
if(p%i==0) vec.push_back(i);
while(p%i==0) p/=i;
}
if(p>1) vec.push_back(p);
k+=cal(x);
ll l=1,r=1e12;
ll ans=-1;
while(l<=r)
{
ll m=(l+r)/2;
if(cal(m)>=k)
{
ans=m;
r=m-1;
}
else l=m+1;
}
printf("%lld\n",ans);
}
return 0;
}