标签:
题意:
你现在来到了一个所有的数都模4余1的世界,也就是除了这种数没有其他的数了。
然而素数的定义依然没变,如果一个数不能写成两个非1数字的乘积,则它是素数。
比如,在这里5就变成了最小的素数。
两个素数相乘得到一个半素数,比如5×5 = 25就是最小的半素数。
求1~h之间有多少个半素数。
分析:
虽然是要求[1, h]之间半素数的个数,但向往常筛普通素数一样先把所有的4k+1的素数筛出来。
然后二重循环枚举半素数,最后统计区间内[1, h]的半素数个数SUMh
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 using namespace std; 5 6 const int maxn = 1000000 + 1; 7 bool vis[maxn + 10]; 8 int prime[100000], cnt, sum[maxn + 10]; 9 10 void Init() 11 { 12 int m = sqrt(maxn + 0.5); 13 for(int i = 5; i <= m; i += 4) if(!vis[i]) 14 for(int j = i * i; j <= maxn; j += i) 15 vis[j] = true;//H-素数筛选 16 17 for(int i = 5; i <= maxn; i += 4) if(!vis[i]) prime[cnt++] = i; 18 19 memset(vis, false, sizeof(vis)); 20 for(int i = 0; i < cnt; i++) 21 {//筛选H-半素数 22 for(int j = i; j < cnt; j++) 23 { 24 long long k = (long long)prime[i] * (long long) prime[j]; 25 if(k > (long long)maxn) break; 26 vis[k] = true; 27 } 28 } 29 30 for(int i = 25; i <= maxn; i++) sum[i] = sum[i-1] + vis[i]; 31 } 32 33 int main() 34 { 35 freopen("in.txt", "r", stdin); 36 Init(); 37 int n; 38 while(scanf("%d", &n) == 1 && n) printf("%d %d\n", n, sum[n]); 39 40 return 0; 41 }
UVa 11105 (筛法) Semi-prime H-numbers
标签:
原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4298333.html