题目大意

求区间[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 质数筛选的更多相关文章

  1. POJ2689 - Prime Distance(素数筛选)

    题目大意 给定两个数L和U,要求你求出在区间[L, U] 内所有素数中,相邻两个素数差值最小的两个素数C1和C2以及相邻两个素数差值最大的两个素数D1和D2,并且L-U<1,000,000 题解 ...

  2. POJ2689 Prime Distance(数论:素数筛选模板)

    题目链接:传送门 题目: Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: Accepted: Des ...

  3. ZOJ 1842 Prime Distance(素数筛选法2次使用)

    Prime Distance Time Limit: 2 Seconds      Memory Limit: 65536 KB The branch of mathematics called nu ...

  4. 解题报告:poj2689 Prime Distance

    2017-10-03 11:29:20 writer:pprp 来源:kuangbin模板 从已经筛选好的素数中筛选出规定区间的素数 /* *prime DIstance *给出一个区间[L,U],找 ...

  5. POJ-2689 Prime Distance (两重筛素数,区间平移)

    Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13961   Accepted: 3725 D ...

  6. POJ-2689 Prime Distance,区间素数筛法

                                                    Prime Distance 只会埃氏筛法的弱鸡今天读了读挑战程序设计120页,明白了求小区间内素数的方 ...

  7. poj 2689 Prime Distance(区间筛选素数)

    Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9944   Accepted: 2677 De ...

  8. poj2689 Prime Distance题解报告

    题目戳这里 [题目大意] 给定一个区间[L,R],求区间内的质数相邻两个距离最大和最小的. [思路分析] 其实很简单呀,很明显可以看出来是数论题,有关于质数的知识. 要注意一下的就是L和R的数据范围都 ...

  9. POJ2689:Prime Distance(大数区间素数筛)

    The branch of mathematics called number theory is about properties of numbers. One of the areas that ...

随机推荐

  1. struts2结果处理、获取参数(二)

    结果处理 1.转发 type可以不写,默认就是转发 <package name="hello" namespace="/hello" extends=&q ...

  2. 自学Python十一 Python爬虫总结

    通过几天的学习与尝试逐渐对python爬虫有了一些小小的心得,我们渐渐发现他们有很多共性,总是要去获取一系列的链接,读取网页代码,获取所需内容然后重复上面的工作,当自己运用的越来越熟练之后我们就会尝试 ...

  3. Struts2 在拦截器中向Action传参

    struts.xml配置文件: <package name="system-default" extends="struts-default" abstr ...

  4. android.system.ErrnoException: open failed: ENOENT (No such file or directory) 07-19 20:27:45.011 66

    在操作安卓版本23+的文件读取时,不仅要在maniests中声明,还要在代码中动态声明: ; private static String[] PERMISSIONS_STORAGE = { Manif ...

  5. easyui combobox的增加全选解决方案

      1.解决方案背景: 项目中偶然需要用到easyui的combobox的组件,但是本组件自己没有包含全选的api事件.搜索了一些解决方案,但是不是很符合,后来发现是因为所使用的版本不一致所导致的.项 ...

  6. JAVA面试题基础部分(二)

    10.使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下 ...

  7. dubbo之回声测试

    回声测试 回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控. 所有服务自动实现 EchoService 接口,只需将任意服务引用强制转型为 EchoSe ...

  8. js replace替换所有字符

    'abc...'.replace(new RegExp('oldStr', 'gm'), 'newStr')

  9. APICloud 获取缓存以及清除缓存(常用第三方方法)

    一.app中经常会有缓存的清除这个操作,具体如下 1.获取缓存大小 apiready = function() { api.getCacheSize(function(ret, err) { //si ...

  10. mac nwjs入门

    NW.js由node-webkit项目发展而来其实很多东西官网上都有.但是鉴于搜索引擎(百度,google)搜索到的相关文章,让人看的很不明白.所以决定写下此篇文章. 官网:https://nwjs. ...