POJ2689 Prime Distance 质数筛选
题目大意
求区间[L, R]中距离最大和最小的两对相邻质数。R<2^31, R-L<1e6。
总体思路
本题数据很大。求sqrt(R)的所有质数,用这些质数乘以j, j+1, j+2...k(j和k使得积属于[L,R])筛选出[L,R]中的合数,然后在[L,R]的质数中得到所求。
筛法求质数
为在O(n)的时间复杂度中求得质数,我们要使筛选时每个可能为质数的数只访问一次。我们用v[i]表示i的最小质因数。每次循环到i时,假设v[i]和小于i的质数都已经在前面求出来了,若v[i]==0,则i是个质数。然后对于每个不大于v[i]的已知质数p,令v[i*p]=p。
不漏
证明:若i+1是个合数,则在处理i+1以前v[i+1]便已知。i+1必然可以化为若干个质数的积,记此质数的集合为P其中最小的质数为a,剩余质数的积为x。显然a<=x<=i。i之前循环到x时,a必然存在于已经求出的质数集合当中(因为a<=x),且a不大于v[x](因为a是P中最小的)。所以一定能由a*x得到i+1。
不重
证明:如果不要求p<=v[i],则值p*i会重复计算若v[i]<=p<=i,则在i循环之前必会循环到p,那个时候就把v[i]*p给算了。
注意
- 本题中质数是从2开始的。
- [L,R]质数中找所求时,避免1的出现,不能直接改循环初始条件。
- 筛选合数时,j至少为2,否则素数乘以1还是素数,我们却把它设成合数了。
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <cstdarg>
- #include <algorithm>
- using namespace std;
- const int INF = 0x3f3f3f3f, MAX_RANGE = 1000010, MAX_SQRT_N = 1 << 16;
- #define LOOP(i, n) for(int i=0; i<n; i++)
- #define LoopFrom(i, l, r) for(int i=l; i<r; i++)
- #define LoopDown(i, n) for(int i=n-1; i>=0; i--)
- int GetPrime(int *ans, int n)
- {
- static int v[MAX_SQRT_N];
- memset(v, 0, sizeof(v));
- int ansCnt = 0;
- LoopFrom(i, 2, n + 1)
- {
- if (!v[i])
- {
- ans[ansCnt++] = i;
- v[i] = i;
- }
- for (int j = 0; j < ansCnt && ans[j] <= v[i] && ans[j] <= n/i; j++)
- v[ans[j] * i] = ans[j];
- }
- return ansCnt;
- }
- void Proceed(int l, int r)
- {
- static int a[MAX_SQRT_N];
- static bool IsPrime[MAX_RANGE];
- memset(a, 0, sizeof(a));
- memset(IsPrime, false, sizeof(IsPrime));
- LOOP(i, r - l + 1)
- IsPrime[i] = true;
- int len = GetPrime(a, sqrt((double)r)+0.5);
- LOOP(i, len)
- LoopFrom(j, max((l / a[i])*a[i] < l ? l / a[i] + 1 : l / a[i], 2), r / a[i] + 1)
- IsPrime[a[i] * j - l] = false;
- int minDist = INF, maxDist = 0, prev = -1;
- int c1=0, c2=INF, d1=0, d2=-INF;
- LoopFrom(i, 0, r - l + 1)
- {
- if (IsPrime[i] && i+l>1)
- {
- if (prev == -1)
- {
- prev = i;
- continue;
- }
- if (i - prev < c2 - c1)
- {
- c1 = prev;
- c2 = i;
- }
- if (i - prev > d2 - d1)
- {
- d1 = prev;
- d2 = i;
- }
- prev = i;
- }
- }
- if (c2 == INF)
- printf("There are no adjacent primes.\n");
- else
- printf("%d,%d are closest, %d,%d are most distant.\n", c1+l, c2+l, d1+l, d2+l);
- }
- int main()
- {
- int l, r;
- while (~scanf("%d%d", &l, &r))
- Proceed(l, r);
- return 0;
- }
筛法求质数2
- void GetPrime(int *prime, int n)
- {
- static bool NotPrime[MAX_N];
- memset(NotPrime,false,sizeof(NotPrime));
- int primeCnt=0;
- for(int i=2; i<=n; j++)
- {
- if(!NotPrime[i])
- prime[primeCnt++]=i;
- for(int j=0; j<primeCnt; j++)
- {
- if(i*prime[j]>N)
- break;
- NotPrime[i*prime[j]]=true;
- if(i%prime[j]==0)
- break;
- }
- }
- }
不重
原则:对于一个数n都由它的最小质因数p和某一个数i相乘得到。
n的最小质因数只有1个,所以n只被访问了一次。
不漏
证明:对于n=p*i,p是n的最小质因数,当外层循环到当前i时,p一定会在循环j时被访问到。
因为n的质因数集合包含i的质因数集合,所以p小于等于i的最小质因数,而循环到当前i时,所有小于i的质数都求出来了,包含着i的最小质因数,故命题成立。
POJ2689 Prime Distance 质数筛选的更多相关文章
- POJ2689 - Prime Distance(素数筛选)
题目大意 给定两个数L和U,要求你求出在区间[L, U] 内所有素数中,相邻两个素数差值最小的两个素数C1和C2以及相邻两个素数差值最大的两个素数D1和D2,并且L-U<1,000,000 题解 ...
- POJ2689 Prime Distance(数论:素数筛选模板)
题目链接:传送门 题目: Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: Accepted: Des ...
- ZOJ 1842 Prime Distance(素数筛选法2次使用)
Prime Distance Time Limit: 2 Seconds Memory Limit: 65536 KB The branch of mathematics called nu ...
- 解题报告:poj2689 Prime Distance
2017-10-03 11:29:20 writer:pprp 来源:kuangbin模板 从已经筛选好的素数中筛选出规定区间的素数 /* *prime DIstance *给出一个区间[L,U],找 ...
- POJ-2689 Prime Distance (两重筛素数,区间平移)
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13961 Accepted: 3725 D ...
- POJ-2689 Prime Distance,区间素数筛法
Prime Distance 只会埃氏筛法的弱鸡今天读了读挑战程序设计120页,明白了求小区间内素数的方 ...
- poj 2689 Prime Distance(区间筛选素数)
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9944 Accepted: 2677 De ...
- poj2689 Prime Distance题解报告
题目戳这里 [题目大意] 给定一个区间[L,R],求区间内的质数相邻两个距离最大和最小的. [思路分析] 其实很简单呀,很明显可以看出来是数论题,有关于质数的知识. 要注意一下的就是L和R的数据范围都 ...
- POJ2689:Prime Distance(大数区间素数筛)
The branch of mathematics called number theory is about properties of numbers. One of the areas that ...
随机推荐
- 5.7 Maven通俗讲解
好的东西只适合ctry+c+v 原文地址:https://blog.csdn.net/shuzhe66/article/details/45009175 Maven通俗讲解 也许是本人不才,初识Mav ...
- 这是一个无效的原路径/url
当我们在SourceTree上新建一个“从URL克隆”的远程项目时,在确认“URL”无误的前提下依然报红色字体“这是一个无效的原路径/URL”错误,我们只需要快捷键“Command + ,”打开Sou ...
- C# 多线程系列(二)
传递数据给一个线程 通过函数或lambda表达式包一层进行传递. static void Main(string[] args) { Thread thread = new Thread(() =&g ...
- bootstrap 图片 图标
一.图片 1.响应式图片:<img src=" " class="responsive"> 2.圆角图片:<img src=" ...
- HTML 5的基本标签
1. 文件开始标签<html> 在任何的一个HTML文件里,最先出现的HTML标签就是<html>,它用于表示该文件是以超文本标识语言(HTML)编写的.<html&g ...
- 国外AI界牛人主页 及资源链接
感觉 好博客要收集,还是贴在自己空间里难忘!!! 原文链接:http://blog.csdn.net/hitwengqi/article/details/7907366 http://people.c ...
- Ad hoc polymorphism
与面向对象中的接口类或抽象类中定义的函数组类似: 函数的具体执行依赖与函数医用的类型. In programming languages, ad-hoc polymorphism[1] is a ki ...
- mysql1064问题完美解决
1.mysql报错code代表具体意思 1005:创建表失败 1006:创建数据库失败 1007:数据库已存在,创建数据库失败 1008:数据库不存在,删除数据库失败 1009:不能删除数据库文件导致 ...
- dmidecode输出详解
一.先来看几个用dmidecode查看内存信息的例子. 1.查看内存槽数.那个槽位插了内存,大小是多少 [root@jiangyi01.sqa.zmf /home/ahao.mah] #dmideco ...
- 设计模式 第一天 UML图,设计模式原则:开闭原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则,简单工厂模式
1 课程大纲 2 UML的概述 总结: UML unified model language 统一建模语言 一共有十种图: 类图 用例图 时序图 * 对象图 包图 组件图 部署图 协作图 状态图 (最 ...