素数筛 欧拉筛 P3383 【模板】线性筛素数

大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn


文章目录

  • P3383 【模板】线性筛素数
    • 题目背景
    • 题目描述
    • 输入格式
    • 输出格式
    • 输入输出样例
    • 说明/提示
    • 参考代码
      • C++版本
      • Java版本

P3383 【模板】线性筛素数

题目背景

本题已更新,从判断素数改为了查询第 kk 小的素数
提示:如果你使用 cin 来读入,建议使用 std::ios::sync_with_stdio(0) 来加速。

题目描述

如题,给定一个范围 n,有 q 个询问,每次输出第 k 小的素数。

输入格式

第一行包含两个正整数 n,q,分别表示查询的范围和查询的个数。

接下来 q 行每行一个正整数 k,表示查询第 k 小的素数。

输出格式

输出 q 行,每行一个正整数表示答案。

输入输出样例

输入 #1复制
100 5
1
2
3
4
5
输出 #1复制
2
3
5
7
11

说明/提示

【数据范围】
对于 100% 的数据, n = 1 0 8 , 1 ≤ q ≤ 1 0 6 n = 10^8 ,1≤q≤10^6 n=1081q106 ,保证查询的素数不大于 n。

参考代码

C++版本

#include 
#include 

bool isPrime[100000010];
//isPrime[i] == 1表示:i是素数
int Prime[6000010], cnt = 0;
//Prime存质数

void GetPrime(int n)//筛到n
{
	memset(isPrime, 1, sizeof(isPrime));
	//以“每个数都是素数”为初始状态,逐个删去
	isPrime[1] = 0;//1不是素数
	
	for(int i = 2; i <= n; i++)
	{
		if(isPrime[i])//没筛掉 
			Prime[++cnt] = i; //i成为下一个素数
			
		for(int j = 1; j <= cnt && i*Prime[j] <= n/*不超上限*/; j++) 
		{
        	//从Prime[1],即最小质数2开始,逐个枚举已知的质数,并期望Prime[j]是(i*Prime[j])的最小质因数
            //当然,i肯定比Prime[j]大,因为Prime[j]是在i之前得出的
			isPrime[i*Prime[j]] = 0;
            
			if(i % Prime[j] == 0)//i中也含有Prime[j]这个因子
				break; //重要步骤。见原理
		}
	}
}

int main()
{
	int n, q;
	scanf("%d %d", &n, &q);
	GetPrime(n);
	while (q--)
	{
		int k;
		scanf("%d", &k);
		printf("%d\n", Prime[k]);
	}
	return 0;
}

Java版本

  • 注意,由于本题输入规模太大,Java输入会超时
/*
 * @Author: motongxue
 * @Date: 2020-08-07 23:26:44
 * @LastEditors: motongxue
 * @LastEditTime: 2020-08-07 23:37:03
 * @Blog: https://motongxue.cn
 * @Description: file content
 */
import java.util.Arrays;
import java.util.Scanner;

public class EulerSieve {
    
    static int[] prime = new int[6000010];  //Prime存质数
    static int cnt = 0;                     // 表示素数个数
    //isPrime[i] == 1表示:i是素数
    static boolean[] isPrime = new boolean[100000010];
    /**
     * 通过欧拉筛筛选从 1-n 的素数
     * @param n
     */
    public static void  GetPrime(int n){
        Arrays.fill(isPrime, true);
        isPrime[1] = false;
        for(int i=2;i<=n;i++){
            if(isPrime[i])prime[++cnt] = i;
            for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
                isPrime[i*prime[j]] = false;
                if(i % prime[j] == 0)//i中也含有Prime[j]这个因子
				break; //重要步骤。见原理
            }
        }
    }
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        int n = sc.nextInt();
        int q = sc.nextInt();
        GetPrime(n);
        while(q-->0){
            int tmp = sc.nextInt();
            System.out.println(prime[tmp]);
        }
    }
}

2020年8月13日更

大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn


你可能感兴趣的:(#,数论)