标签:
题目大意:这道题中给了一种数的定义,让求在某个区间内的这种数的个数。这种数的定义是:有且只有一个素因子的合数。
题目分析:这种数的实质是素数的至少两次幂。由此打表——打出最大区间里的所有这种数构成的表即可。
代码如下:
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 }
对于这一类问题:一定要理解透彻题中的新定义,否则费了半天劲写出来的东西是错的,既浪费时间,又浪费精力。
UVA-10539 Almost Prime Numbers
标签:
原文地址:http://www.cnblogs.com/20143605--pcx/p/4708946.html