大区间素数筛选 POJ2689
题意:
给一个区间[L,U],(1<=L< U<=2,147,483,647),U-L<=1000000,求出[L,U]内距离近期和距离最远的素数对。
因为L,U都小于2^32,所以区间内的合数的最小质因子必定小于2^16,所以先筛出2^16以内的素数,用筛出来的素数去筛[L,U]内的合数。然后把[L,U]内的素数保存下来,再搜索近期和最远的素数对就可以。注意两整数相乘可能溢出32位,注意对1的推断。
代码:
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include<climits>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std; #define PB push_back
#define MP make_pair #define REP(i,x,n) for(int i=x;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define FORD(i,h,l) for(int i=(h);i>=(l);--i)
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define OI(X) printf("%d",X);
#define RS(X) scanf("%s", (X))
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)
#define Dpoint strcut node{int x,y}
#define cmpd int cmp(const int &a,const int &b){return a>b;} /*#ifdef HOME
freopen("in.txt","r",stdin);
#endif*/
const int MOD = 1e9+7;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long LL;
typedef pair<int,int> PII;
//#define HOME int Scan()
{
int res = 0, ch, flag = 0; if((ch = getchar()) == '-') //推断正负
flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0'; return flag ? -res : res;
}
/*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/
#define MAXN 100000
int prime[MAXN];
int vis[MAXN+5];
int cnt;
void getprime()
{cnt=0;
for(int i=2;i<=MAXN;i++)
if(!vis[i])
{
prime[cnt++]=i;
for(int j=0;j<cnt&&prime[j]<=MAXN/i;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
} } int notprime[1000000+5];
int prime2[1000000+5];
int cnt2;
void getprime2(int L,int U)
{ for(int i=0;i<cnt;i++)
{ if(prime[i]>=U)
break;
int s=L/prime[i];
if(s<=1)
s=2;
for(int j=s;(long long)prime[i]*j<=U;j++)
if((long long )prime[i]*j>=L)
{
notprime[(long long )prime[i]*j-L]=1;
}
}
cnt2=0;
REP(i,0,U-L+1)
{
if(!notprime[i]&&(i+L)!=1&&(i+L)!=0)
prime2[cnt2++]=i+L; } } int main()
{getprime();
int L,U;
while(RII(L,U)!=EOF)
{
MS0(notprime);
getprime2(L,U);
int ans1=INT_MAX;
int ans2=0;
int n1,n2,f1,f2;
if(cnt2<2)
{
printf("There are no adjacent primes.\n");
continue;
}
REP(i,0,cnt2-1)
{
if(prime2[i+1]-prime2[i]<ans1)
{
ans1=prime2[i+1]-prime2[i];
n1=prime2[i];
n2=prime2[i+1];
}
if(prime2[i+1]-prime2[i]>ans2)
{
ans2=prime2[i+1]-prime2[i];
f1=prime2[i];
f2=prime2[i+1];
}
}
printf("%d,%d are closest, %d,%d are most distant.\n",n1,n2,f1,f2);
} return 0;
}
大区间素数筛选 POJ2689的更多相关文章
- LightOJ1197 Help Hanzo —— 大区间素数筛选
题目链接:https://vjudge.net/problem/LightOJ-1197 1197 - Help Hanzo PDF (English) Statistics Forum Tim ...
- LightOJ 1197 LightOJ 1197(大区间素数筛选)
http://lightoj.com/volume_showproblem.php?problem=1197 题目大意: 就是给你一个区间[a,b]让你求这个区间素数的个数 但a.b的值太大没法直接进 ...
- 大区间素数筛选(POJ 2689)
/* *POJ 2689 Prime Distance *给出一个区间[L,U],找出区间内容.相邻的距离最近的两个素数和距离最远的两个素数 *1<=L<U<=2147483647 ...
- LightOj 1197 Help Hanzo (区间素数筛选)
题目大意: 给出T个实例,T<=200,给出[a,b]区间,问这个区间里面有多少个素数?(1 ≤ a ≤ b < 231, b - a ≤ 100000) 解题思路: 由于a,b的取值范围 ...
- 2017ACM暑期多校联合训练 - Team 4 1003 HDU 6069 Counting Divisors (区间素数筛选+因子数)
题目链接 Problem Description In mathematics, the function d(n) denotes the number of divisors of positiv ...
- poj 2689 Prime Distance(大区间素数)
题目链接:poj 2689 Prime Distance 题意: 给你一个很大的区间(区间差不超过100w),让你找出这个区间的相邻最大和最小的两对素数 题解: 正向去找这个区间的素数会超时,我们考虑 ...
- LightOJ 1197 Help Hanzo(区间素数筛选)
E - Help Hanzo Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Submit ...
- M - Help Hanzo LightOJ - 1197 (大区间素数筛法)
题解:素数区间问题.注意到a和b的范围是1<<31,所以直接暴力打表肯定不可以.如果一个数是合数,他的两个因子要么是两个sqrt(x),要么就分布在sqrt(x)两端,所以我们可以根据sq ...
- Prime Count 求大区间素数个数
http://acm.gdufe.edu.cn/Problem/read/id/1333 https://www.zhihu.com/question/29580448/answer/44874605
随机推荐
- [topcoder]SmartWordToy
广度搜索BFS,要用Queue.还不是很熟,这道题帮助理清一些思绪了.其实这道题是求最短路径,所以BFS遇到第一个就可以返回了,所以后面有些现有大小和历史大小的判断可以省却. 过程中拿数组存step还 ...
- 如何在Blog中使用feedburner管理RSS订阅
http://www.cnblogs.com/procoder/archive/2010/02/12/feedburner.html
- 交叉编译 小米路由器mini 的 python(MIPS)
看了很多文章,要么说的是用opkg安装python,要么说的是小米路由器的交叉编译,就是没有mini的.学习了这篇文章(http://me.deepgully.com/post/56389167868 ...
- prim(与边无关,适合稠密的图,o(n^2))---还是畅通工程
题目1017:还是畅通工程 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1653 解决:838 题目描述: 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“ ...
- 如何用C#获得文件信息以及扩展信息
在C#中获得文件信息很容易,只需要用FileInfo类或者FileVersionInfo类就可以获得,但是如果想要获得文件的扩展信息,则无法从这两类来获得.不过在C#中,这也不是件难事,只要引入“Mi ...
- Outlook接收qq的邮件
1.先去qq邮箱,设置,账户 开启pop3服务,假如之前开启过,最好关闭之后重新开启 最新版本的必须使用邮箱的独立密码才可以收取邮件 (否则就算你之前开通了,也无法用你的qq账号和密码收取邮件的) 2 ...
- WCF - Creating WCF Service
http://www.tutorialspoint.com/wcf/wcf_creating_service.htm Creating a WCF service is a simple task u ...
- Oracle EBS R12 WIP Component Issue&Return Process
oracleassemblytransactionscomponentsjobsreference 目录(?)[-] 定义BOM 定义Routing 定义WIP Discrete Job 发料 Mat ...
- maven 简单实用教程
1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具. 目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本. 1.2. Maven资源 ...
- phpcms 2008 /preview.php SQL注入漏洞
漏洞版本: phpcms 2008 漏洞描述: phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台. phpcms 2008的preview ...