Semi-prime H-numbers POJ 3292(素数筛)

原题

题目链接

题目分析

由题意可知,我们要做的第一步就是把H-prime筛出来,仔细观察可以发现,如果i是H-prime,则i*i+4*k*i(k=0,1,2,3...)也是H-prime,这里为了方便筛可以把原数x表示为x/4.筛出H-prime后就暴力处理出H-composites(记得去重).最后排一下序,询问的话直接lower_bound查找就行了.

代码

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <utility>
 6 #include <ctime>
 7 #include <cmath>
 8 #include <cstring>
 9 #include <string>
10 #include <stack>
11 #include <queue>
12 #include <vector>
13 #include <set>
14 #include <map>
15 
16 using namespace std;
17 typedef long long LL;
18 const int INF_INT=0x3f3f3f3f;
19 const LL INF_LL=0x3f3f3f3f3f3f3f3f;
20 
21 int is_prime[300000];
22 int prime[100000];
23 int cnt;
24 int ans[200000];
25 int k;
26 
27 void pre()
28 {
29     for(int i=1;i<=250000;i++) is_prime[i]=true;
30     for(int i=1;i<=250000;i++)
31     {
32         if(is_prime[i])
33         {
34             int d=(4*i+1);
35             prime[cnt++]=d;
36             for(LL j=(LL)d*d/4;j<=250000;j+=d) is_prime[j]=false;
37         }
38     }
39     bool s=false;
40     for(int i=0;i<cnt;i++)
41     {
42         for(int j=i;j<cnt;j++)
43         {
44             LL t=prime[i]*prime[j];
45             if(t>1000001)
46             {
47                 if(i==j) s=true;
48                 break;
49             }
50             ans[k++]=t;
51         }
52         if(s) break;
53     }
54     sort(ans,ans+k);
55     k=unique(ans,ans+k)-ans;
56 }
57 
58 int main()
59 {
60 //    freopen("black.in","r",stdin);
61 //    freopen("black.out","w",stdout);
62     pre();
63 //    for(int i=0;i<k;i++) printf("%d %d\n",ans[i],i+1);
64 
65     int x;
66     while(~scanf("%d",&x)&&x)
67     {
68         int t=lower_bound(ans,ans+k,x)-ans;
69         printf("%d ",x);
70         if(x==ans[t]) printf("%d\n",t+1);
71         else printf("%d\n",t);
72     }
73 
74     return 0;
75 }

猜你喜欢

转载自www.cnblogs.com/VBEL/p/11444611.html