Dertouzos
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 577 Accepted Submission(s): 160
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
思路:
题目要求的是,在小于n的范围内,找出所有最大除数为d的数。假设满足该条件的一个数y,那么y=x*d,x为y的最小质因子。因为x已经无法再分解为2个大于1的数 x=a*b,使得 y=a*(b*d)。 接下来再看,另slove(n)表示n的最小质因子。如果d是非质数 那么d=slove(d)*k,y=x*k*slove(d)并且x*k<=d,由此可得x<=solve(d),因为若x>solve(d),那么x*k>d,d就不是y的最大除数了;如果d是质数,那么solve(d)=d,也满足以上结论。
同时题目还限定范围小于n,那么可以得出x<=(n-1)/d。综上所述,取2种情况的并集,那么就是 x<=min(solve(d),(n-1)/d)并且x是质数。并且由于
(n-1)/d,那么x最大不会超过sqrt(n),所以先把sqrt(1e9)内的素数先筛选 用数组存起来,然后再暴力枚举x就可以了。
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #define lson l,m,rt*2 16 #define rson m+1,r,rt*2+1 17 #define mod 1000000007 18 #define INF 1000000006 19 using namespace std; 20 typedef long long LL; 21 int n,d,k,p; 22 vector<LL> Q; 23 bool vis[1000000+5]; 24 void init() 25 { 26 for(LL i=2;i<=1000000+5;i++) 27 { 28 if(!vis[i]) 29 { 30 Q.push_back(i); 31 for(LL j=i*i;j<=1000000+5;j+=i) 32 { 33 vis[j]=true; 34 } 35 } 36 } 37 } 38 int main() 39 { 40 #ifdef Local 41 freopen("data.txt","r",stdin); 42 #endif 43 int T,i,j,h,r,sum=0,m,ans,flag,q,mid,l; 44 cin>>T; 45 init(); 46 while(T--) 47 { 48 ans=flag=0; 49 scanf("%d%d",&n,&d); 50 n=(n-1)/d; 51 for(i=0;Q[i]<=n&&i<Q.size();i++) 52 { 53 ans++; 54 if((d%Q[i])==0)break; 55 } 56 cout<<ans<<endl; 57 } 58 }