【题意】就是给一个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);
        }
    }
}