poj 2689 大范围内素数筛选


 1 /**
2 给定一定范围求其内的素数
3
4 注意:
5 **/
6
7 #include <iostream>
8 #include <math.h>
9 #include <cstring>
10 using namespace std;
11 #define maxn 1000000
12 long long prime[500000];
13 long long cprime[500000];
14 long long isprime[maxn+100];
15 long long vis[maxn+100];
16 long long q;
17 void getprime(){
18 //memset(isprime,0,sizeof(isprime));
19 q =-1;
20 long long i,j;
21 isprime[0] = isprime[1] =1;
22 for(i=2;i<maxn;i++){
23 if(!isprime[i])
24 prime[++q] = i;
25 for(j=0;j<=q&&prime[j]*i<maxn;j++){
26 isprime[prime[j]*i] =1;
27 if(i%prime[j]==0)
28 break;
29 }
30 }
31 }
32
33 long long qt;
34 void getprime1(long long a, long long b){
35 qt =-1;
36 if(b<maxn){
37 for(long long i=a;i<=b;i++){
38 if(!isprime[i])
39 cprime[++qt] = i;
40 }
41 }else{
42 memset(vis,0,sizeof(vis));
43 long long i,k;
44 for(i=0;i<=b-a;i++){
45 vis[i] =1;
46 }
47 for(i=0;prime[i]*prime[i]<=b&&i<=q;i++){
48 k = a/prime[i];
49 if(k*prime[i]<a) k++;
50 if(k<=1) k++;
51 while(k*prime[i]<=b){
52 vis[k*prime[i]-a] =0;
53 k++;
54 }
55 }
56 for(i=0;i<=b-a;i++){
57 if(vis[i]==1)
58 cprime[++qt] = i+a;
59 }
60 }
61
62 }
63 int main()
64 {
65 getprime();
66 //for(int i=0;i<10;i++)
67 // cout<<prime[i]<<endl;
68 long long a,b;
69 while(cin>>a>>b){
70 long long maxnum =-1;
71 long long minnum =0x3f3f3f3f;
72 getprime1(a,b);
73 long long max1,max2,min1,min2;
74 // for(int i=0;i<=qt;i++)
75 // cout<<cprime[i]<<endl;
76 for(long long i=0;i<qt;i++){
77 long long temp = cprime[i+1]-cprime[i];
78 if(temp>maxnum){
79 maxnum =temp;
80 max1 = cprime[i];
81 max2 = cprime[i+1];
82 }
83 if(temp<minnum){
84 minnum =temp;
85 min1 = cprime[i];
86 min2 = cprime[i+1];
87 }
88 }
89 if((qt+1)<=1)
90 cout<<"There are no adjacent primes."<<endl;
91 else
92 cout<<min1<<","<<min2<<" are closest, "<<max1<<","<<max2<<" are most distant."<<endl;
93 }
94 return 0;
95 }

poj 2689 大范围内素数筛选

时间: 2024-11-06 15:35:37

poj 2689 大范围内素数筛选的相关文章

POJ 2689 Prime Distance(素数筛选)

题目链接:http://poj.org/problem?id=2689 题意:给出一个区间[L, R],找出区间内相连的,距离最近和距离最远的两个素数对.其中(1<=L<R<=2,147,483,647) R - L <= 1000000 思路:数据量太大不能直接筛选,要采用两次素数筛选来解决.我们先筛选出2 - 50000内的所有素数,对于上述范围内的数,如果为合数,则必定有2 - 50000内的质因子.换一句话说,也就是如果一个数没有2 - 50000内的质因子,那么这个数为素

《挑战程序设计竞赛》 大区间内素数的个数

题意: 给一个区间边界值很大的区间,但是区间大小较小,求出该区间内所有质数个数. 知识补充: 因数枚举:分解一个数n,至于要从1 枚举到 n??√ 即可,然后把i和 n / i 当做因数加入vector 整数分解(把一个整数枚举出其质数基连乘的形式):从2开始枚举质数基,然后每次把该整数尽可能的被当前质数除去最大次数,这样该整数就会变小,极大减少枚举量.注意和map搭配使用,记录每一个质数的个数. 埃式素数筛法的复杂度是:Ologlogn看做线性也无妨. 求区间[a,b)内素数的个数,由于b的最

POJ 2689 Prime Distance(素数区间筛法--经典题)

大致题意:给定[L,R]区间,找出区间内的每个素数 数据范围 : 1<=L< R<=2,147,483,647) R-L <=1,000,000. R的数值太大,所以不能直接筛[0,R]的,要空间和时间优化,用到区间筛法,另外注意不能用int,因为R和L都是满int的,中间有很多细节处理会爆int的,还要注意1不是素数,所以在区间筛中要特判一下,是个易错的地方 //1160K 16MS C++ 1539B #include<cstdio> #include<ios

POJ 2689 Prime Distance 素数筛选法应用

题目来源:POJ 2689 Prime Distance 题意:给出一个区间L R 区间内的距离最远和最近的2个素数 并且是相邻的 R-L <= 1000000 但是L和R会很大 思路:一般素数筛选法是拿一个素数 然后它的2倍3倍4倍...都不是 然后这题可以直接从2的L/2倍开始它的L/2+1倍L/2+2倍...都不是素数 首先筛选出一些素数 然后在以这些素数为基础 在L-R上在筛一次因为 R-L <= 1000000 可以左移开一个1百万的数组 #include <cstdio>

POJ 2689 二次筛选(映射)

Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12303   Accepted: 3296 Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number th

POJ 2689 - Prime Distance - [筛法求素数]

题目链接:http://poj.org/problem?id=2689 Time Limit: 1000MS Memory Limit: 65536K Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number theoreticians for thousan

POJ 2773 Happy 2006#素数筛选+容斥原理+二分

http://poj.org/problem?id=2773 说实话这道题..一点都不Happy好吗 似乎还可以用欧拉函数来解这道题,但正好刚学了容斥原理和二分,就用这个解法吧. 题解:要求输出[1,m]中与m互质的第k个数,先打表,找到m的所有质因数,然后用二分实现,最开始区间为[1,2^60],利用容斥原理去找区间[1,mid]内素数的个数t,不断进行二分,直到所查找的区间[l,r]内素数的个数t等于k,mid=l=r,则此时的l就是第k个与m互质的数. #include<iostream>

poj 2689 Prime Distance 【数论】【筛法求素数】

题目链接:传送门 题目大意: 给你L和R两组数,L和R的范围是2^32,其间隔(即R-L最大为1,000,000.) .让你求出L和R之间素数的最大间隔和最小的间隔. 比如 2 17.之间的最小素数间隔是2 3,最大的素数间隔是11 17. 要是直接进行一个2^32次方筛法然后在判断是会T的. 我们这样来想,筛法求素数的原理是什么: /**vis数组标记为0则说明是素数*/ int vis[10005]; void getPrimevis(int n) { int m=sqrt(n+0.5);

LightOJ 1197 LightOJ 1197(大区间素数筛选)

http://lightoj.com/volume_showproblem.php?problem=1197 题目大意: 就是给你一个区间[a,b]让你求这个区间素数的个数 但a.b的值太大没法直接进行素数筛选(没法开那么大的数组),我们可以将a当做0,将b当做b-a 这样求[a,b]之间就变成了求[0, b - a]之间,这样就可以开数组来筛选 下图是代码式子j = j + prime[i] - a % prime[i]的由来 #include<stdio.h> #include<ma