Problem A
Almost Prime Numbers
Time Limit: 1 second
Almost prime numbers are the non-prime numbers which are divisible by only a single prime number. In this problem your job is to write a program which finds out the number of almost prime numbers within a certain range.
Input
First line of the input file contains an integer N (N <= 600) which indicates how many sets of inputs are there. Each of the next N lines make a single set of input. Each set contains two integer numbers low and high (0 < low <= high < 1012).
Output
For each line of input except the first line you should produce one line of output. This line contains a single integer, which indicates how many almost prime numbers are within the range (inclusive) low…high.
Sample Input | Sample Output |
3 1 10 1 20 1 5 |
3 4 1 |
Problemsetter: Shahriar Manzoor, special thanks to Derek Kisman
题目大意:
这道题说的是,给你一个[l,r],然后让你在这个[l,r]中,找到仅仅含有一个素数因子并且自己不是素数的数的个数。
解题思路:
一看题,就知道是数学题,那么我们上来后先打表就是了。
首先,我们先看看第一组样例[1,10]有3个,那么答案就是4,8,9这三个了?为什么是这三个数字呢?首先4=2*2 = 2^2.仅含有一个素数因子,这个因子是2.
然后是8 = 2*4 = 2^3也含有一个素数因子,这个因子是2,然后是 9 = 3*3 = 3^2,含有素数因子3。
不难发现,要想找到自己不是素数,并且仅仅含有一个素因子的数的等价于在这个区间中去寻找是否存在这样的数字val使得对于任意的一个素数p有val = p^i;(i>=2)
当然,val的值肯定是介于l和r之间的。
在最初的素数打表的过程中,我们只需要计算出p^2<=10^12 -> p<=10^6.
所以,只需要计算出[1,10^6]的素数就好了,然后我们从pime[i]*prime[i]开始枚举,直到其数值超过了r为止。。。
代码:
1 # include<cstdio> 2 # include<iostream> 3 # include<cstring> 4 5 using namespace std; 6 7 typedef long long LL; 8 9 # define MAX 1000004 10 11 LL prime[MAX]; 12 LL book[MAX]; 13 LL len; 14 15 void init() 16 { 17 for ( int i = 2;i <= MAX;i++ ) 18 { 19 book[i] = 1; 20 } 21 for ( int i = 2;i <= MAX;i++ ) 22 { 23 if ( book[i]==1 ) 24 { 25 for ( int j = 2*i;j <= MAX;j+=i ) 26 { 27 book[j] = 0; 28 } 29 } 30 } 31 for ( int i = 2;i <= MAX;i++ ) 32 { 33 if ( book[i]==1 ) 34 { 35 prime[len++] = i; 36 } 37 } 38 39 } 40 41 42 int main(void) 43 { 44 init(); 45 int t;cin>>t; 46 while ( t-- ) 47 { 48 LL tot = 0; 49 LL l,r; 50 cin>>l>>r; 51 for ( int i = 0;i < len;i++ ) 52 { 53 for ( LL j = prime[i]*prime[i];j <= r;j*=prime[i] ) 54 { 55 if ( j >= l ) 56 { 57 // cout<<j<<endl; 58 tot++; 59 } 60 } 61 62 } 63 cout<<tot<<endl; 64 65 } 66 67 return 0; 68 }