Prime Distance(poj2689变形的筛法素数)
2013-10-17 21:51
239 查看
题意:给你一个区间L,U计算这个区间里面的间距最大的连续素数和最小的连续素数1<=L< U<=2,147,483,647,L,U的间距不超过1000000.
思路:L,U的范围太大了无法使用普通的筛法,将所有素数全部筛完,但是因为它是L,U的一个区间,长度不超过10^6,那可以筛出这个区间的所有素数,然后再求最大最小间距
怎么求L,U区间的素数呢?
我们可以先看1<=L< U<=2,147,483,647这个区间的素数,最大的因子也就是根号2,147,483,647 = 47000,根据筛法的操作,先把2花圈,然后删除2的其他倍数,然后3花圈,删除3的其他倍数,一直删到根号2,147,483,647这个区间就只剩下素数了。
关键是怎么确定开始的L开始的2,3,5....的倍数,这时我们可以用 整数的强制转换 L / prime[i] * prime[i] 这样就正好转换为正好是要删除的prime[i]的倍数,但是还有一点这个开始的数要不小于L,要不去了也没用不在区间里,如果他小于L,继续加prime[i],如果正好整除prime[i]不要删除,素数除以它本身,即它是花圈的那个数,让它从下一个开始,一定记住从花圈的下一个数开始。
思路:L,U的范围太大了无法使用普通的筛法,将所有素数全部筛完,但是因为它是L,U的一个区间,长度不超过10^6,那可以筛出这个区间的所有素数,然后再求最大最小间距
怎么求L,U区间的素数呢?
我们可以先看1<=L< U<=2,147,483,647这个区间的素数,最大的因子也就是根号2,147,483,647 = 47000,根据筛法的操作,先把2花圈,然后删除2的其他倍数,然后3花圈,删除3的其他倍数,一直删到根号2,147,483,647这个区间就只剩下素数了。
关键是怎么确定开始的L开始的2,3,5....的倍数,这时我们可以用 整数的强制转换 L / prime[i] * prime[i] 这样就正好转换为正好是要删除的prime[i]的倍数,但是还有一点这个开始的数要不小于L,要不去了也没用不在区间里,如果他小于L,继续加prime[i],如果正好整除prime[i]不要删除,素数除以它本身,即它是花圈的那个数,让它从下一个开始,一定记住从花圈的下一个数开始。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; long long p[1000008]; long long pp[1000008]; bool prim[1000008]; bool fp[1000008]; long long Isp() { long long k = 0; prim[0] = prim[1] = 1; memset(prim,0,sizeof(prim)); for(long long i = 2; i <= 47000; i++) { if(!prim[i]) { p[k++] = i; for(long long j = i*i; j <= 47000; j += i) { prim[j] = 1; } } } return k; } void fun(long long L,long long U,long long cnt) { long long i,j,b,k = 0; memset(fp,1,sizeof(fp)); for(i = 0; i < cnt; i++) { b = L / p[i]; while(b*p[i] < L || b <= 1) b++; for(j = b*p[i]; j <= U; j+=p[i]) { fp[j-L] = 0; } if(L == 1) fp[0] = 0; } } int main() { long long U,L; long long cnt = Isp(); while(scanf("%I64d%I64d",&L,&U) != EOF) { long long sum = 0; fun(L,U,cnt); int Max = -999999,Min = 9999999; long long flagMax = 0,flagMin = 0; for(long long i = 0; i <= U-L; i++) { if(fp[i]) { pp[sum++] = L+i; } } if(!sum || sum == 1) { printf("There are no adjacent primes.\n");continue; } for(int i = 0; i < sum-1; i++) { if(pp[i+1] - pp[i] > Max) { Max = pp[i+1] - pp[i];flagMax = i; } if(pp[i+1] - pp[i] < Min) { Min = pp[i+1] - pp[i];flagMin = i; } } printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",pp[flagMin],pp[flagMin+1],pp[flagMax],pp[flagMax+1]); } return 0; }
相关文章推荐
- POJ 2689 Prime Distance(素数区间筛法--经典题)
- poj 2689 Prime Distance 筛法+区间筛素数
- Prime Distance - POJ 2689 素数筛选
- 数论 - 素数的运用 --- poj 2689 : Prime Distance
- poj 2689 Prime Distance 筛法/二次筛法/区间素数
- POJ 2689 Prime Distance [筛法选取素数]【数论】
- POJ 2689 Prime Distance【大区间素数筛选】【埃氏筛法】【经典题】
- poj 2689 Prime Distance (素数二次筛法)
- poj-2689-大区间求素数
- poj 2689(区间筛选素数。。。很经典)
- POJ题目2689 Prime Distance(任何区间素数筛选)
- poj 2689 Prime Distance (double筛筛出大素数)
- POJ 2689 Prime Distance [素数筛+想法]
- POJ2689-Prime Distance-区间筛素数
- poj 2689 Prime Distance 二次筛法
- POJ 2689 Prime Distance 素数筛选 -
- POJ 2689 Prime Distance(大区间素数筛法,两次筛法)
- POJ 3292 Semi-prime H-numbers(筛法变形)
- poj 2689 Prime Distance(大区间筛素数)
- [ACM] POJ 2689 Prime Distance (大区间素数筛选)