题意:给你x、p、k三个数,让你求大于x的第k个与p互素的数?
思路:求出p的质因子,然后求小于等于x的与p互质的个数求出为j,题意就相当于求大于0的第k+j个与p互素的数了,二分枚举答案,求小于等于某一个数与p互质的个数使用容斥原理计算得出。
代码:
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 1000000007
using namespace std;
typedef long long ll;
int x, p, k;
int prime[1000005], ji=0, shu[105], jj=1;
int pa[1000005];
int Solve(int x,int a,int type)
{
if(a==jj)
{
return x * type;
}
else
{
return Solve(x,a+1,type) + Solve(x/shu[a],a+1,type * -1);
}
}
int main()
{
int t;
scanf("%d",&t);
pa[0]=pa[1]=1;
for(int i=2; i*i<=1000000; i++)
{
if(!pa[i])
{
prime[ji++]=i;
for(int j=i*i; j<=1000000; j=j+i)
{
pa[j]=1;
}
}
}
for(int i=1000;;i++)
{
if(!pa[i])
{
prime[ji++]=i;
break;
}
}
while(t--)
{
jj=1;
scanf("%d%d%d",&x,&p,&k);
for(int i=0; prime[i]*prime[i]<=p; i++)
{
int flag=1;
while(p%prime[i]==0)
{
if(flag)
{
flag=0;
shu[jj++]=prime[i];
}
p=p/prime[i];
}
}
if(p>1)
shu[jj++]=p;
if(p==1&&jj==0)
{
printf("%d\n",x+k);
continue;
}
k=k+Solve(x,1,1);
int l=x, r=1000000005;
while(r-l>1)
{
int mid=(l+r)/2;
if(Solve(mid,1,1)>=k)
{
r=mid;
}
else
{
l=mid;
}
}
cout << r << endl;
}
return 0;
}

京公网安备 11010502036488号