首先我们都会求[1,n]与给定的p互质的个数对吧?用容斥原理,拿n-1个p的质因子+2个p的质因子...这样容斥下去即可.
题目是要求大于x第k个与p互质的数.很明显是有单调性的,我们来二分n然后ck一下,假定cnt[n]表示[1,n]与给定的p互质的个数,那么我们是要求大于x的第k个,那么我们直接拿cnt[n]-cnt[x]看他假如多了,我们就缩小r,少了就增加l...然后就没了..
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=24;
int id,pr[N],sum;
int query(int x)//查询1~x与p互质数的个数.
{
int res=0;
for(int i=0;i<(1<<id);i++)
{
int num=0,s=1;
for(int j=0;j<id;j++)
if(i>>j&1) {num++;s*=pr[j+1];}
if(num&1) res-=x/s;//减
else res+=x/s;//加
}
return res;
}
int main()
{
int T,x,p,k;
scanf("%d",&T);
while(T--)
{
id=0;
scanf("%d%d%d",&x,&p,&k);
if(p==1) { printf("%d\n",x+k); continue; }
int temp=p;
for(int i=2;i*i<=temp;i++)
{
if(temp%i==0) pr[++id]=i;
while(temp%i==0) temp/=i;
}
if(temp>1) pr[++id]=temp;//所有质因子
sum=query(x);
int l=x,r=2e7,ans=2e9;
while(l<=r)
{
int mid=(l+r)>>1;
if(query(mid)-sum>=k)
{
r=mid-1;
ans=min(mid,ans);
}
else l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}
京公网安备 11010502036488号