SPOJ Problem Set 2. Prime Generator 求某区间质数题解

题目大意: 给定两个数,要求产生这两个数之间的所有质数。

两个数位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之间的所有质数

如何产生质数表? 这都是用到往前搜索,剔除不符合条件的数,避免过多的重复计算,带点动态规划的味道。

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

#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;
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索generator
, 质数
, 题目
, 两个
, 区间
范围
prime generator、spoj qtree、spoj1812、spoj 375、spoj lcs2,以便于您获取更多的相关知识。

时间: 2024-08-30 08:13:45

SPOJ Problem Set 2. Prime Generator 求某区间质数题解的相关文章

hdu vector-hdu 3823 prime friend 求大神为什么wa,已经wa怕了

问题描述 hdu 3823 prime friend 求大神为什么wa,已经wa怕了 http://acm.hdu.edu.cn/showproblem.php?pid=3823 #include<stdio.h> #include<vector> using namespace std; #define M 20000010 bool pri[M] = {0}; int ans[M],temp = 0; vector<int>fans[152]; int abs(in

Excel教程 如何求指定区间内的工作天数

  如果能直接在表格中轻松计算出来,这样在人事部工作的人员得到很大的帮助,到底是怎么实现的,下面一起来看看吧. 具体操作步骤: 1.打开一份需要计算工作日的表格,我们在D2单元格输入公式: =networkdays(B2,C2). 2.回车得到结果21,在2010年1月份,出去周六和周日,工作日有21天. 3.双击填充柄,下拉得到结果,我们勾选不用格式填充. 4.然后在E11输入公式: =networkdays(B11,C11,A16:A18). 5.回车结果显示20,其中不包含节假日,也就是国

树状数组专题【完结】

1 国外的论文点击打开链接 2 我的总结点击打开链接 任何能够造成树状数组下表为0的操作都会使得程序TLE,这是个很重要的地方! 第一题 poj 2299 Ultra-QuickSort 点击打开poj 2299 思路: 离散化+树状数组 分析: 1 题目的意思就是要求逆序数对 2 题目的输入个数有500000的规模但是每个数的最大值为999999999,因此我们需要离散化这些数据 3 对于数据9 1 0 5 4我们离散化成5 2 1 4 3 那么对于输入一个树a[i]我们去求一下它的离散化后的

HIT 1867 经理的烦恼

点击打开HIT 1867 思路: 树状数组 分析: 1 题目要求的是给定一个区间求这个区间质数的个数 2 题目给定n条命令和每个店的初始的值,那么我们初始化的时候就要通过判断给定的初始值是否为质数来初始化 3 因为要求的是质数的个数,那么我们可以这么想,假设现在改变了店铺x的值,那么我们通过判断前后是否是质数的关系来更新树状数组 4 求区间的质数的个数的时候直接求即可 代码: #include<cmath> #include<cstdio> #include<cstring&

UVa 524 Prime Ring Problem:数论&amp;amp;DFS

524 - Prime Ring Problem Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=465 A ring is composed of n (even number) circles as shown in diagram. Put natural numbers into e

UVa 10924 Prime Words:素数

10924 - Prime Words Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1865 A prime number is a number that has only two divisors: itself and the number one.

uva 100 The 3n+1 problem

题目链接: http://www.programming-challenges.com/pg.php?page=studenthome /* The 3n+1 problem 计算每个数的循环节长度,求给定区间的循环节长度的最大值. */ #include<iostream> #include<stdio.h> using namespace std; int jk(int n) { int num=1; while(n!=1) { if(n&1) n+=(n<<

求质数的算法 (合集)

一.利用BitSet(筛法)  import java.util.*;public class BitSetTest{public static void main(String[] args){BitSet sieve=new BitSet(1024);int size=sieve.size();for(int i=2;i< size;i++)sieve.set(i);int finalBit=(int)Math.sqrt(sieve.size()); for(int i=2;i< fina

excel表格中如何使用函数求平均值?

  excel表格中如何使用函数求平均值?           步骤 1.打开表格,锁定要求平均值的单元格 2.选定单元后,点击表格上方 "公式",出现下图界面 3.在公式一栏中,找到自动求和图标,点击图标,出现下拉链,找到"平均值". 4.点击"平均值",出现如下函数公式,虽然看着比较乱,但是不要慌,我们离成功越来越近啦. 5.不管上图看着怎样乱,我们只要淡定的同时按下键盘上"Ctrl"和"Enter"健