NowCoder猜想(素数筛法+位压缩)

  在期末被各科的大作业碾压快要窒息之际,百忙之中抽空上牛客网逛了逛,无意中发现一道好题,NowCoder猜想,题意很明显,就是个简单的素数筛法,但竟然超内存了,我晕(+﹏+)~  明明有 3 万多 k 的空间限制……于是我不打表,试了试最暴力的做法,赤裸裸的做法果然超时了,无奈,只好对素数筛法进行位压缩了,这是我目前所能想到的方法了,第一次用上这样的特技,还是调了好一会(位数组里不能用 bool 来定义,具体的话好像 bool 和 int 之类的整型稍有不同;也不能用 int,因其最高位是正负标志位,所以只好用 unsigned int了,同样的原理,用 unsigned char, unsigned short, unsigned long long 等无符号整型都可以),贴个代码先,注释的为纯暴力:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int inf = 0x3fffffff;
 8 const int N = 1e7;
 9 
10 class bitarray {
11     unsigned int sign[320000];
12 public:
13     bitarray() {  memset(sign,0,sizeof(sign));  }
14     bool rid(const int &x) const {
15         return sign[x / 32] & (1 << (x % 32));
16     }
17     void wid(const int &x, const int &v) {
18         sign[x / 32] |=  (v ? (1 << (x % 32)) : 0);
19     }
20 };
21 
22 int pri[700005];
23 int init_pri(int n = N) {
24     bitarray bit;
25     int c = 0;
26     for(int i = 2; i <= n; ++i)
27         if(!bit.rid(i)) {
28             pri[c++] = i;
29             for(int j = i << 1; j <= n; j += i)   bit.wid(j,1);
30         }
31     return c;
32 }
33 
34 /*
35 inline bool isprime(const int &x) {
36     if(x == 1)  return 0;
37     int m = sqrt(x +0.5);
38     for(int i = 2; i <= m; ++i)
39         if(x % i == 0)  return 0;
40     return 1;
41 }
42 
43 inline int num(const int &n) {
44     int res = 0;
45     for(int i = 1; i <= n; i += 2)
46         if(isprime(i))  ++res;
47     return  n >= 2 ? res + 1 : res;
48 }
49 */
50 
51 int main() {
52     int n,num = init_pri();
53     pri[num++] = inf;
54     while(~scanf("%d",&n),n) {
55         int id = lower_bound(pri, pri+num, n) - pri;
56         if(pri[id] == n)    printf("%d
",id + 1);
57         else    printf("%d
",id);
58     }
59     return 0;
60 }
View Code

   提交后发现无论是哪种做法,后台的内存计算都和我自己手算的差很远,不知它是怎么计算的。。。

原文地址:https://www.cnblogs.com/Newdawn/p/4620972.html