poj2689(素数区间筛法模板)

摘要:
a:b;24}2526intmain{27get_prime();28lll,r;29while{30memset;31for{32lla=/prime[i];33llb=r/prime[i];34for{//筛[l,r]内的合数35vis[prime[i]*j-l]=1;//减个l方便标记,输出答案时加回去即可36}37}38ifvis[0]=1;//注意这个1并不是素数39llcnt=-1,sol1=MAXN,sol2=0,x1,y1,x2,y2;40for{41if{42if(cnt!

题意: 给出一个区间 [l, r] 求其中相邻的距离最近和最远的素数对 . 其中 1 <= l < r <= 2,147,483,647, r - l <= 1e6 .

思路: 素数区间筛

要找到 [l, r] 中相邻最近和最远的素数对肯定是需要找出 [l, r] 内所有素数 . 但是无论是直接线性打表还是暴力都处理不了这么大的数据 .

可以先给 sqrt(r) 内的素数打个表, 再用 sqrt(r) 内的素数去筛选 [l, r] 内的合数, 然后再遍历一次 [l, r], 记录答案即可 .

1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 #define ll long long
5 using namespacestd;
6 
7 const int MAXN = 1e6 + 10;
8 const int MAX =1e5;
9 intprime[MAX], tag[MAX], vis[MAXN], tot;
10 
11 void get_prime(void){
12     for(int i = 2; i < MAX; i++){
13         if(!tag[i]){
14             prime[tot++] =i;
15             for(int j = 2; j * i < MAX; j++){
16                 tag[j * i] = 1;
17 }
18 }
19 }
20 }
21 
22 ll Max(ll a, ll b){
23     return a > b ?a : b;
24 }
25 
26 int main(void){
27 get_prime();
28 ll l, r;
29     while(~scanf("%lld%lld", &l, &r)){
30         memset(vis, 0, sizeof(vis));
31         for(int i = 0; i < tot; i++){
32             ll a = (l + prime[i] - 1) /prime[i];
33             ll b = r /prime[i];
34             for(int j = Max(2, a); j <= b; j++){ //筛[l, r]内的合数
35                 vis[prime[i] * j - l] = 1; //减个l方便标记,输出答案时加回去即可
36 }
37 }
38         if(l == 1) vis[0] = 1; //注意这个1并不是素数
39         ll cnt = -1, sol1 = MAXN, sol2 = 0, x1, y1, x2, y2;
40         for(int i = 0; i <= r - l; i++){
41             if(vis[i] == 0){
42                 if(cnt != -1){
43                     if(sol1 > i -cnt){
44                         x1 =cnt;
45                         y1 =i;
46                         sol1 = i -cnt;
47 }
48                     if(sol2 < i -cnt){
49                         x2 =cnt;
50                         y2 =i;
51                         sol2 = i -cnt;
52 }
53 }
54                 cnt =i;
55 }
56 }
57         if(sol2 == 0) puts("There are no adjacent primes.");
58         else printf("%lld,%lld are closest, %lld,%lld are most distant.
", x1 + l, y1 + l, x2 + l, y2 +l);
59 }
60     return 0;
61 }
View Code

免责声明:文章转载自《poj2689(素数区间筛法模板)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇APIView的使用php的精度计算问题(bcadd和bcsub)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

判断一个数是否是素数

判断一个数是否是素数: 输入一个数,判断是否是素数;第一行输入一个整数n,表示有n组测试数据; 第二行输出结果,每组测试数据占一行。 1 //素数判断 2 #include<stdio.h> 3 int isprime(int num) //自定义函数判断是否是是素数 4 { 5 int flag=1; 6 inti; 7...

素数回文(高效判断素数法)

Problem Description xiaoou33对既是素数又是回文的数特别感兴趣。比如说151既是素数又是个回文。现在xiaoou333想要你帮助他找出某个范围内的素数回文数,请你写个程序找出 a 跟b 之间满足条件的数。(5 <= a < b <= 100,000,000);   Input 这里有许多组数据,每组包括两组数据a...

使用c语言和GMP库实现伪随机算法笔记

步骤一:安装GMP库,两种方法选其一既可 1.使用源码安装方式: 2.使用在线安装的方式: 步骤二:使用GMP库随机生成一个大数,样本代码如下: 步骤三:使用GMP库随机生成一个大数,并判断生成的大数是不是素数,样本代码如下: 步骤四:根据生成的大素数,产生下一个大素数,样本代码如下: 步骤五:根据随机产生的大素数和随机数,使用BlumBlumShus算...

NYOJ 975

这道题一开始本着很朴素的想法就是先输入两头的数据,然后对每组的数据范围下测试中间的数据即可,但是是超时的。原因也很明显,比如计算1~1000的数据之后,假如下一组数据是1~1001,本来只需要多测试下1001是否符合再加上前面的结果(1~1000)即可,而这种做法需要重复计算。 能够ac的处理方式是打表。就是分别计算1~n (n的范围是1~1000005)...

中国石油大学(华东)计算机复试C语言参考题库

目录 复试c语言 【研究创新型】8.1 谁能出线 【设计型】8.2 统计素数的个数 【设计型】8.3 数组逆序输出 【设计型】8.4 在屏幕上显示杨辉三角形 【设计型】8.5 求最大值 【设计型】8.6 二维数组 【设计型】8.11 存储并输出一个矩阵 【设计型】8.7 给数组中的元素按顺序编号 【设计型】8.8 求各位数字组成的最大数 【设计型】8...

超级素数幂--全国模拟(一)

[编程题] 超级素数幂 时间限制:1秒 空间限制:32768K 如果一个数字能表示为p^q(^表示幂运算)且p为一个素数,q为大于1的正整数就称这个数叫做超级素数幂。现在给出一个正整数n,如果n是一个超级素数幂需要找出对应的p,q。  输入描述: 输入一个正整数n(2 ≤ n ≤ 10^18)     输出描述: 如果n是一个超级素数幂则输出p,q,以空格...