Uva 10539 Almost Prime Numbers

题意:寻找特定区间内满足本身不是素数,但只有一个素因子的数。

这道题我一开始做了个超时(交的时候又忘记了测试大数。。。)。我原先是打算正向计算,对于每一个数判断他是否是素数,是否是只有一个素因子。这种思路能做,只是算法时间复杂度不符合题目要求。原题数组组数有几百,最大的数有10^12...

通过这个题目,我得到两个经验:

遇到特别大的数,八成是要打表做。

正向想不通的,逆向做或许更简单。

先找出所有素数,根据素数构造所有满足条件的数是这道题的可行思路。

因为素数的二次方以及以上一定不是素数并且只有一个素因子,只要保证这个数小于10^12,所以我们可以从表中查找我们输入的值。因为数据量比较大,我们排序后用二分查找寻找上下界,相减就是结果。

另外,注意我这里用的求素数的方法。这种方法比较高效。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int smaxn = 1000000;
 4 vector<long long > notprime;
 5 bool vis[smaxn +1] ={false};
 6 int primes[smaxn];
 7 const long long int maxn = 1000000000000LL;
 8 void store_prime(){
 9     int cnt = 0;
10     int m = (int )sqrt(smaxn + 0.5);
11     for(int i = 2; i<=m;i++)if(!vis[i])
12         for(int j = i*i; j <=smaxn;j+=i)vis[j] = 1;
13     for(int i=2;i<=smaxn;i++)if(!vis[i])primes[cnt++] = i;
14     for(int i =0; i< cnt;i++){
15         long long d = primes[i];
16         while(1){
17             d*=primes[i]; 
18             if(d >= maxn) break;
19             notprime.push_back(d);
20         }
21     }
22 }
23 int main(){
24     int n;
25     store_prime();
26     sort(notprime.begin(),notprime.end());
27     scanf("%d",&n);
28     while(n--){
29         long long  L, U;
30         scanf("%lld%lld",&L,&U);
31         long long a = upper_bound(notprime.begin(),notprime.end(),U) -notprime.begin() ;
32         long long b = lower_bound(notprime.begin(),notprime.end(),L) -notprime.begin() ;
33         printf("%lld
",a-b);
34     }
35     return 0;
36 }
原文地址:https://www.cnblogs.com/Wade-/p/6392016.html