题意:在【2,n-1】里找出有多少个数,使得 该数的最大“约数”为d,
这里约数不包括自身。
设该数为y,y=xd<=n 首先x<=floor【(n-1)/d】,然后可以发现,x一定是y的一个最小质因子,否则d可以更大,然后x还要小于等于d的最小质因子,否则d也可以更大,
也就是x<=min(floor((n-1)/d),d的最小质因子) , d的最小质因子肯定不超过sqrtn级别的,然后可以打出sqrt(1e9)的素数表(大约3400个),然后暴力找
另一种是,
素筛法打biao【i】到1e6,代表i的最小素因子
则ans=min(biao[i],(n-1)/d),在prim二分找一下多少个比它小即可
当n>1e6,min的第一个参数会不超过1000,直接暴力
代码1:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N = 31622+2;
bool f[N+50];
int prim[N];
int biao[N+50];
int main()
{
int ok=0;
//素数打表
f[1]=true;
for (long long i=2; i<=N; i++) //1处
{
if (f[i]==false) //优化
{
prim[++ok]=i;
for (long long j= i*i; j<=N; j=j+i) // 如果1处用1000必须_int64强制转换
{
f[j]=true;
}
}
}
/* for (int i=1; i<=ok; i++)
{
biao[prim[i]]=prim[i];
for (long long j= (long long)prim[i]*prim[i]; j<=1e6; j=j+prim[i])
{
if (0==biao[j])
biao[j]=prim[i];
}
}*/
int n, a, d;
int t;
cin>>t;
while(t--)
// while(scanf("%d", &n)!=EOF)
{
scanf("%d%d",&n,&d);
int cun=0;
for (int i=1; i<=ok; i++)
{
if (1LL*prim[i]*d<=n) cun++;
else break;
if (d%prim[i]==0)break;
}
printf("%d\n",cun);
}
return 0;
}
代码2:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N = 1e6+2;
bool f[N+50];
int prim[N];
int biao[N+50];
int main()
{
int ok=0;
//素数打表
f[1]=true;
for (long long i=2; i<=N; i++) //1处
{
if (f[i]==false) //优化
{
prim[++ok]=i;
for (long long j= i*i; j<=N; j=j+i) // 如果1处用1000必须_int64强制转换
{
f[j]=true;
}
}
}
for (int i=1; i<=ok; i++)
{
biao[prim[i]]=prim[i];
for (long long j= (long long)prim[i]*prim[i]; j<=1e6; j=j+prim[i])
{
if (0==biao[j])
biao[j]=prim[i];
}
}
/* printf("%d\n",prim[ok]);
for (int i=(210)-200;i<=210;i++)
printf("%d ",biao[i]);*/
int n, a, d;
int t;
cin>>t;
while(t--)
// while(scanf("%d", &n)!=EOF)
{
scanf("%d%d",&n,&d);
if (d>1e6)
{
int cun=0;
for (int i=1; i<=ok; i++)
{
if (1LL*prim[i]*d<=n) cun++;
else break;
if (d%prim[i]==0)break;
}
printf("%d\n",cun);
}
else
{
int idx=min(biao[d],(n-1)/d);
int it=upper_bound(prim+1,prim+1+ok,idx)-prim;
printf("%d\n",it-1);
}
}
return 0;
}