题意:
给定n,d,求小于n的且d为其非自身最大因子的数的个数。
思路:
要d是最大因子,这个数x=d*k,k必须是<=(d的最小因子)的一个素数,且k<n/d&&k<=d。
若k为合数,k=a*b(a,b不为1和d),那a*d就比d大,矛盾。
若k为质数,k>d的最小因子c,d'=d/c*k>d,矛盾。
答案即为2~min([n/d],d的最小因子)中质数的个数(个数在筛的时候求小前缀和就好)。
先用素数筛就出1~50000的素数,大约5000个,检验每个<[n/d]的素数是不是d的因子,取第一个检验到的,如果没有就取[n/d]。
最后输出答案。
#include<iostream> #include<string.h> #include<cstdio> using namespace std; bool isprime[50001]; int coun[50001]; int prime[10000]; int primecnt=0; void steve(){ for(int i=2;i<50000;i++){ if(isprime[i])prime[++primecnt]=i; for(int j=1;j<=primecnt&&i*prime[j]<50000;j++){ isprime[i*prime[j]]=0; if(i%prime[j]==0)break; } } } int main(){ memset(isprime,1,sizeof(isprime)); int n; cin>>n; steve(); for(int i =2;i<50000;i++) if(isprime[i]) coun[i]=coun[i-1]+1; else coun[i]=coun[i-1]; int a,b,c,d; for(int i=0;i<n;i++){ scanf("%d%d",&a,&b); c=a/b; if(b*c==a)c--; for(int j=1;prime[j]<=c&&j<=primecnt;j++) if(b%prime[j]==0){ b=prime[j]; break; } b=min(b,c); printf("%d\n",coun[b]); } return 0; }