质数
【例题】Prime Distance(poj2689)
这题L,R范围很大,但是L,R差值在可以接受的范围内。因为一个数n的质因子不会超过 n−−√ n ,所以我们考虑线筛预处理 R−−√ R 范围内所有的质数,在线筛的的同时标记L到R范围的合数。
如何标记:对每一个质数p,枚举一个倍数i,将i*p标记为合数。i的范围是 ⌊Lp⌋≤i≤⌊Rp⌋ ⌊ L p ⌋ ≤ i ≤ ⌊ R p ⌋ (因为 L≤i∗p≤R L ≤ i ∗ p ≤ R )。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int pri[50010],pr;
bool v[50010];
void get_prime(int n)
{
memset(v,true,sizeof(v));
pr=0;
for(int i=2;i<=n;i++)
{
if(v[i]) pri[++pr]=i;
for(int j=1;(j<=pr)&&(i*pri[j]<=n);j++)
{
v[i*pri[j]]=false;
if(i%pri[j]==0) break;
}
}
}
bool f[1000010];
int main()
{
int L,R;
get_prime(50000);
while(scanf("%d%d",&L,&R)!=EOF)
{
if(L==1) L=2;
memset(f,true,sizeof(f));
for(int i=1;i<=pr;i++)
{
int l=(L-1)/pri[i]+1;
int r=R/pri[i];
for(int j=l;j<=r;j++)
if(j>1)
f[j*pri[i]-L]=false;
}
int last=-1,maxx=-1,minn=2147483647,a,b,c,d;
for(int i=0;i<=R-L;i++)
{
if(f[i])
{
if(last==-1){last=i; continue;}
if(i-last<minn)
{
minn=i-last;
a=last+L,b=i+L;
}
if(i-last>maxx)
{
maxx=i-last;
c=last+L,d=i+L;
}
last=i;
}
}
if(maxx==-1) puts("There are no adjacent primes.");
else printf("%d,%d are closest, %d,%d are most distant.\n",a,b,c,d);
}
return 0;
}
【例题】阶乘分解(传送门)
本题前提是阶乘,所以所有小于N的数都会出现,那么 N