HDU 4548 美素数 在线打表加数状数组

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4548

解题报告:一开始本想先打个素数表,然后每次输入L 跟R 的时候都进行暴力判断,但这题测试数据太多,有1W ,这样就达到10^10级别了,很明显不能过,但是,我后来一想,数状数组不就是用来解决区间问题的吗,顿时焕然大吾。我的做法就是先打个1到1000000的素数表,然后暴力判断从1到1000000每个数是不是美素数,同时把结果存到数状数组里面去。这样就可以实现存完了就可以实现快速查找了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 
 6 const int maxn = 1000000;
 7 
 8 int prim[maxn+5],tree[maxn+5];
 9 
10 void dabiao()
11 {
12     memset(prim,0,sizeof(prim));
13     prim[1] = 1;
14     for(int i = 4;i <= maxn;i += 2)
15     prim[i] = 1;
16     int M = sqrt(maxn);
17     for(int i = 2;i <= M;++i)
18     if(prim[i] == 0)
19     for(int j = i*i;j<=maxn;j+=i)
20     prim[j] = 1;
21 }
22 
23 
24 int judge(int n)
25 {
26     int sum = 0;
27     while(n)
28     {
29         sum += n%10;
30         n /= 10;
31     }
32     return sum;
33 }
34 
35 void add(int n)
36 {
37     if(n > maxn)
38     return ;
39     for(int i = n;i <= maxn;i += (i&-i))
40     tree[i]++;
41 }
42 void dabiao2()
43 {
44     memset(tree,0,sizeof(tree));
45     for(int i = 1;i <= maxn;++i)
46     if(!prim[i] && !prim[judge(i)])
47     add(i);
48 }
49 
50 int sum(int L,int R)
51 {
52     int tot1 = 0,tot2 = 0;
53     for(int i = L-1;i >= 1; i -= (i&-i))
54     tot1 += tree[i];
55     for(int i = R;i >= 1;i -= (i&-i))
56     tot2 += tree[i];
57     return tot2 - tot1;
58 }
59 
60 int main()
61 {
62     dabiao();
63     dabiao2();
64     int T,L,R,l = 1;
65     scanf("%d",&T);
66     while(T--)
67     {
68         scanf("%d %d",&L,&R);
69         printf("Case #%d: %d\n",l++,sum(L,R));
70     }
71     return 0;
72 }
View Code

 

posted @ 2013-09-16 21:18  xiaxiaosheng  阅读(271)  评论(0编辑  收藏  举报