题意:求出与p互质并且大于x的第k个数
思路:首先我们可以求出p的所有质因子,可以根据a/b表示[1,a]中以b为因子的数的个数,然后用这个通过容斥来求得[1,a]中与与p互质的数的个数,然后就可以愉快地二分了。
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader sc = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Task solver = new Task();
solver.solve(1, sc, out);
out.close();
}
static class Task {
public int getCnt(int x,ArrayList<Integer> factor) { //二进制枚举容斥
int ans=x;
for(int i=1;i<(1<<(factor.size()));i++) {
int cnt=0;
int temp=1;
for(int j=0;j<factor.size();j++) {
if((i&(1<<j))!=0) {
temp*=factor.get(j);
cnt++;
}
}
if(cnt%2==1) //注意符号
ans-=x/temp;
else
ans+=x/temp;
}
return ans;
}
public boolean check(int x,int k,int preCnt,ArrayList<Integer> factor) {
return getCnt(x,factor)-preCnt>=k;
}
public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
ArrayList<Integer> factor=new ArrayList<Integer>();
int T=sc.nextInt();
while(T-->0) {
factor.clear();
int x=sc.nextInt();
int p=sc.nextInt();
int k=sc.nextInt();
for(int i=2;i*i<=p;i++) {
if(p%i==0)
factor.add(i);
while(p%i==0)
p/=i;
}
if(p!=1)
factor.add(p);
int preCnt=getCnt(x,factor);
int l=x+1;
int r=(int) 1e7;
int ans=-1;
while(l<=r) {
int mid=(l+r)>>1;
if(check(mid,k,preCnt,factor)) {
r=mid-1;
ans=mid;
}
else
l=mid+1;
}
out.println(ans);
}
}
}
static class InputReader{
StreamTokenizer tokenizer;
public InputReader(InputStream stream){
tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
tokenizer.ordinaryChars(33,126);
tokenizer.wordChars(33,126);
}
public String next() throws IOException {
tokenizer.nextToken();
return tokenizer.sval;
}
public int nextInt() throws IOException {
return Integer.parseInt(next());
}
public long nextLong() throws IOException {
return Long.parseLong(next());
}
public boolean hasNext() throws IOException {
int res=tokenizer.nextToken();
tokenizer.pushBack();
return res!=tokenizer.TT_EOF;
}
public double nextDouble() throws NumberFormatException, IOException {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() throws IOException {
return new BigInteger(next());
}
}
}