Let's denote as L(x, p) an infinite sequence of integers y such that gcd(p, y) = 1 and y > x (where gcd is the greatest common divisor of two integer numbers), sorted in ascending order. The elements of L(x, p) are 1-indexed; for example, 9, 13 and 15 are the first, the second and the third elements of L(7, 22), respectively.
You have to process t queries. Each query is denoted by three integers x, p and k, and the answer to this query is k-th element of L(x, p).
The first line contains one integer t (1 ≤ t ≤ 30000) — the number of queries to process.
Then t lines follow. i-th line contains three integers x, p and k for i-th query (1 ≤ x, p, k ≤ 106).
Print t integers, where i-th integer is the answer to i-th query.
3 7 22 1 7 22 2 7 22 3
9 13 15
5 42 42 42 43 43 43 44 44 44 45 45 45 46 46 46
187 87 139 128 141
题意:找出第k个大于x且与p互质的数
题解:二分这个数,然后容斥计算这个数字是否符合要求即可,预处理好每个数的因数,然后直接对每个数拆分因子即可。
代码:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int x,p,k,t;
vector<int>e[1000005];
int cal(int x)
{
int len=e[p].size(),ans=0;
for(int i=1;i<(1<<len);i++)
{
int s=1,cnt=0;
for(int j=0;j<len;j++)
if((i>>j)&1) s*=e[p][j],cnt++;
if(cnt&1) ans+=x/s;
else ans-=x/s;
}
return x-ans;
}
int main()
{
for(int i=2;i<=1000000;i++)
if(!e[i].size())
for(int j=i;j<=1000000;j+=i)
e[j].push_back(i);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&x,&p,&k);
int tmp=cal(x),l=x,r=2147483647,ans=x+1;
while(l<=r)
{
int mid=(l+r)/2;
if(cal(mid)-tmp>=k) r=mid-1,ans=mid;
else l=mid+1;
}
printf("%d\n",ans);
}
}