Dertouzos
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1643 Accepted Submission(s): 514
Problem Description
A positive proper divisor is a positive divisor of a number
n
, excluding
n
itself. For example, 1, 2, and 3 are positive proper divisors of 6, but 6 itself is not.
Peter has two positive integers n and d . He would like to know the number of integers below n whose maximum positive proper divisor is d .
Peter has two positive integers n and d . He would like to know the number of integers below n whose maximum positive proper divisor is d .
Input
There are multiple test cases. The first line of input contains an integer
T
(1≤T≤106)
, indicating the number of test cases. For each test case:
The first line contains two integers n and d (2≤n,d≤109) .
The first line contains two integers n and d (2≤n,d≤109) .
Output
For each test case, output an integer denoting the answer.
Sample Input
9 10 2 10 3 10 4 10 5 10 6 10 7 10 8 10 9 100 13
Sample Output
1 2 1 0 0 0 0 0 4
Source
Recommend
官方题解:
随便推导下, 令y=xd, 如果d是y的maximum positive proper divisor, 显然要求x是y的最小质因子. 令mp(n)表示n的最小质因子, 那么就有x≤mp(d), 同时有y<n, 那么x≤⌊dn−1⌋. 于是就是计算有多少个素数x满足x≤min{mp(d),⌊dn−1⌋}.
当d比较大的时候, ⌊dn−1⌋比较小, 暴力枚举x即可. 当d比较小的时候, 可以直接预处理出答案. 阈值设置到106∼107都可以过.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int prime[(int)1e5+5];
void getP(int MAXN)
{
memset(prime,0,sizeof(prime));
for(int i=2; i<=MAXN; i++)
{
if(!prime[i])prime[++prime[0]]=i;
for(int j=1; j<=prime[0]&&prime[j]<=MAXN/i; j++)
{
prime[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
}
int main()
{
getP((int)1e5+5);
int t;
scanf("%d",&t);
while(t--){
int n,d;
scanf("%d%d",&n,&d);
int ans=0;
for(int i=1;i<=prime[0];i++){
if(prime[i]*d>=n) break;//枚举质因子,若质因子×d>=上限说明已统计完毕
++ans;
if(d%prime[i]==0) break;//考虑到maximum positive proper divisor也是合数的情况
}
printf("%d\n",ans);
}
return 0;
}