SPOJ Problem Set 2. Prime Generator 求某区间质数题解
2014-04-16 12:32
337 查看
题目大意: 给定两个数,要求产生这两个数之间的所有质数。
两个数位m和n,其范围如下:
The input begins with the number t of test cases in a single line (t<=10). In each of the
next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.
看似简单的题目,其实也不简单,一般的质数判断方法是,看这个数n能否被2到根号n之间的数除尽,如果不能,那么就是质数,当然,这里这么写程序是会超时的。
查表方法也不行,如果先产生所有的质数表,那么内存太大了,不能保存。一般现在都使用区间剔除的方法。
目前我知道的本题最快的就是二次区间剔除的方法了:
1 先产生2到32000(32000的平方大于1E9)之间的质数,作为一个质数表(增加这个质数表也是为了加速)
2 再产生n到m之间的所有质数
如何产生质数表? 这都是用到往前搜索,剔除不符合条件的数,避免过多的重复计算,带点动态规划的味道。
两个数位m和n,其范围如下:
The input begins with the number t of test cases in a single line (t<=10). In each of the
next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.
看似简单的题目,其实也不简单,一般的质数判断方法是,看这个数n能否被2到根号n之间的数除尽,如果不能,那么就是质数,当然,这里这么写程序是会超时的。
查表方法也不行,如果先产生所有的质数表,那么内存太大了,不能保存。一般现在都使用区间剔除的方法。
目前我知道的本题最快的就是二次区间剔除的方法了:
1 先产生2到32000(32000的平方大于1E9)之间的质数,作为一个质数表(增加这个质数表也是为了加速)
2 再产生n到m之间的所有质数
如何产生质数表? 这都是用到往前搜索,剔除不符合条件的数,避免过多的重复计算,带点动态规划的味道。
#include <iostream> #include <vector> #include <string.h> using namespace std; class PrimeNumberGenerator { const static int MAX_NUM = 32000; int PRIMES[MAX_NUM]; int segPrimes[100000]; public: PrimeNumberGenerator() { memset(PRIMES, 0, sizeof(PRIMES)); int j = 0; for (int i = 2; i < MAX_NUM; i++) { if (!PRIMES[i]) { PRIMES[j++] = i; for (int k = i*2; k < MAX_NUM; k+=i)//不是k++注意 {//写成 k = i+1,头痛错误!!! PRIMES[k] = 1; } } } PRIMES[j++] = MAX_NUM; } //本题不需使用的函数 bool isPrimeNum(int num) { if (2 == num) return true; int i = 0; for ( ; PRIMES[i] * PRIMES[i] <= num && num % PRIMES[i]; i++); return MAX_NUM != PRIMES[i] && num % PRIMES[i] != 0; } void getSegPrimes(int a, int b) { memset(segPrimes, 0, sizeof(segPrimes));//每一次都需要memset for (int i = 0; PRIMES[i]*PRIMES[i] <= b; i++)//错误写成i <= b-a { int am = a/PRIMES[i]; for (int d = am; d * PRIMES[i] <= b; d++) { if (d > 1 && d * PRIMES[i] >= a) segPrimes[d*PRIMES[i]-a] = 1; }//这里不能少了判断条件d>1 } } void judgePrimes() { int a = 0, b = 0; int T = 0; cin>>T; while (T--) { cin>>a>>b; if (a < 2) a = 2; getSegPrimes(a, b); for (int i = a ; i <= b; i++) { if (0 == segPrimes[i-a]) cout<<i<<endl; } cout<<endl; } } }; int main() { PrimeNumberGenerator pri; pri.judgePrimes(); return 0; }
相关文章推荐
- 【SPOJ-PRIME1】Prime Generator【区间质数筛】
- HDU 5700 区间交 百度之星题解 round2B (set+vector)
- 【BZOJ】【P2318】【Spoj4060 game with probability Problem】【题解】【概率DP】
- SPOJ Problem Set (classical) 11582. A Famous Grid
- [SPOJ IITWPC4F Gopu and the Grid Problem]线段树区间翻转
- ZOJ Problem Set - 3469(区间dp)
- SPOJ 2713(GSS4-线段树区间开方-多组数据)
- SPOJ 18249 IITWPC4F - Gopu and the Grid Problem(线段树)
- 求区间[1,N]的质数的个数(1≤N≤10^11)
- ZOJ Problem Set - 3640 Help Me Escape
- 1374 - Confusion in the Problemset
- A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
- SPOJ3267 D-Query 树状数组离线操作 或 主席树 查询某一区间内有多少不同的数
- ZOJ Problem Set - 1003 Crashing Balloon
- 开区间[L, R]中的整数L,R;在此区间中所有质数的个数n
- nefu 118 质数在阶乘中的幂 http://acm.nefu.edu.cn/test/problemshow.php?problem_id=118
- ZOJ Problem Set - 2109 FatMouse' Trade
- ZOJ Problem Set - 1970 All in All
- DP18 分割区间问题 Partition problem @geeksforgeeks
- ZOJ Problem Set - 3204 Connect them