UVA-10539 Almost Prime Numbers

题目大意:这道题中给了一种数的定义,让求在某个区间内的这种数的个数。这种数的定义是:有且只有一个素因子的合数。

题目分析:这种数的实质是素数的至少两次幂。由此打表——打出最大区间里的所有这种数构成的表即可。

代码如下:

 1 # include<iostream>
 2 # include<cstdio>
 3 # include<cmath>
 4 # include<set>
 5 # include<cstring>
 6 # include<algorithm>
 7 using namespace std;
 8 const long long N=1000000000000;
 9 # define ll long long
10 int pri[80000],mark[1000005];
11 set<ll>s;
12 ll mypow(int a,int b)
13 {
14     if(b==1)
15         return a;
16     ll u=mypow(a,b/2);
17     u*=u;
18     if(b&1)
19         u*=a;
20     return u;
21 }
22 void init()
23 {
24     pri[0]=0;
25     memset(mark,0,sizeof(mark));
26     for(int i=2;i<=1000000;++i){
27         if(!mark[i])
28             pri[++pri[0]]=i;
29         for(int j=1;j<=pri[0]&&i*pri[j]<=1000000;++j){
30             mark[i*pri[j]]=1;
31             if(i%pri[j]==0)
32                 break;
33         }
34     }
35     for(int i=1;i<=pri[0];++i){
36         ll u=(pri[i]+0LL)*(pri[i]+0LL);///在这要对pri[i]进行强制类型转换,否则溢出。
37         while(u<N){
38             s.insert(u);
39             u=u*pri[i];
40         }
41     }
42 }
43 void work(ll a,ll b)
44 {
45     int ans=0;
46     set<ll>::iterator it1,it2;
47     it1=lower_bound(s.begin(),s.end(),a);
48     it2=lower_bound(s.begin(),s.end(),b);
49     while(it1!=it2){
50         ++it1;
51         ++ans;
52     }
53     printf("%d\n",ans);
54 }
55 int main()
56 {
57     init();
58     int T;
59     ll l,r;
60     scanf("%d\n",&T);
61     while(T--)
62     {
63         scanf("%lld%lld",&l,&r);
64         work(l,r);
65     }
66     return 0;
67 }

 对于这一类问题:一定要理解透彻题中的新定义,否则费了半天劲写出来的东西是错的,既浪费时间,又浪费精力。

posted @ 2015-08-06 19:31  20143605  阅读(170)  评论(0编辑  收藏  举报