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\n",id + 1);

57         else    printf("%d\n",id);

58     }

59     return 0;

60 }
View Code

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

你可能感兴趣的:(code)