【题意】就是给一个n和一个d,问有多少个小于n的数的最大因子是d
【解题方法】
个数为min((n-1)/d,d')d'为d的最小质因子;素数筛,然后枚举最小质因子
【AC代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1000000;
int prime[maxn];
bool is[maxn];
int p;
int ret[maxn];
void sieve()
{
//int p=0;
memset(prime,0,sizeof(prime));
memset(ret,0,sizeof(ret));
for(int i=0; i<maxn; i++) is[i]=true;
is[0]=is[1]=false;
for(int i=2; i<maxn; i++){
if(is[i]){
prime[p++]=i;
ret[i]=i;
for(int j=2*i; j<maxn; j+=i){
is[j]=false;
if(!ret[j]) ret[j]=i;
}
}
}
}
//要求最小质因子,顺序枚举
//int solve(int x){
// for(int i=(int)(sqrt)(x+0.5); i>=0; i--){
// if(x%i==0){
// return i;
// }
// }
//}
int main()
{
sieve();
int T;
scanf("%d",&T);
while(T--)
{
int n,d;
scanf("%d%d",&n,&d);
int temp=(int)(n-1)/d;
if(n>=maxn){
bool flag=0;
for(int i=0; prime[i]<=temp; i++){
if(d%prime[i]==0){
flag=1;
int ans=upper_bound(prime,prime+p,prime[i])-prime;
printf("%d\n",ans);
break;
}
}
if(flag==0){
int ans=upper_bound(prime,prime+p,temp)-prime;
printf("%d\n",ans);
}
}else{
int minn=min(temp,ret[d]);
int ans=upper_bound(prime,prime+p,minn)-prime;
printf("%d\n",ans);
}
}
}