题意:
分析:
我写的有点麻烦…
先求1e5内的素数,然后就可以搞除1e5内的合数
然后就可以求1e5内每个数的合因子的个数
发现最大的合因子个数也不超过122
然后做个二维数组
存小于j且合因子个数为i的数的个数
访问的时候直接输出
即可
应该有更简单的写法,到时候会添加
代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
#define Pll make_pair
using namespace std;
typedef long long ll;
const int MAXN=1e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int phi=1e9+6;
int k;
int su[MAXN],c,b[MAXN];
bool a[MAXN];
int he[MAXN];
void prime()//素数筛
{
memset(a,1,sizeof(a));
a[0]=a[1]=0;
c=1;
for(int i=2;i<=MAXN;i++)
{
if(a[i]==1)
su[c]=i,b[i]=c,c++;
for(int j=1;j<c&&su[j]*i<MAXN;j++) {
a[su[j] * i] = 0;
if(i%su[j]==0)break;
}
}
}
int p[MAXN];
int pk[130][MAXN];
int main()
{
prime();
int cnt=0;
for(int i=4;i<=MAXN;i++){
if(a[i]==0)he[++cnt]=i;//合数
}
//cout<<he[1]<<" "<<he[2]<<" "<<he[3]<<endl;
for(int i=1;i<=cnt;i++){
for(int j=he[i];j<=MAXN;j+=he[i])//合数的倍数,肯定有这个合数作为他的因子
p[j]++;
}
int ma=0;
for(int i=1;i<=MAXN;i++)
ma=max(ma,p[i]);
//cout<<ma<<endl;
memset(pk,0, sizeof(pk));
for(int i=1;i<=122;i++)
for(int j=4;j<=MAXN;j++){
pk[i][j]=pk[i][j-1];
if(p[j]==i)pk[i][j]++;//遇到等于i的++
}
//cout<<pk[2][8]<<endl;
int n,m;
scanf("%d%d",&n,&m);
while(m--){
//int ans=0;
scanf("%d",&k);
if(k>122)
printf("0\n");//特判,小于1e5的数的合因子个数不可能超过122
else
printf("%d\n",pk[k][n]);
}
return 0;
}
/*
*/