您的位置:首页 > 其它

LightOJ - 1197 Help Hanzo 较大数的区间素数筛法

2017-11-28 22:47 441 查看
题意:

给定 a,b ,求 [a, b] 之间素数的个数,

思路:

由于a,b比较大,直接暴力判素数也不行,

我们可能会想到筛法,但是会遇到没法用数组存的问题,这样的话可以用 0 ~ (b-a)大小的数组存;给定了大小 1e6

先打素数表,每次把a b之间的非素数筛掉,还有可能的是a-b之间的第一个prim i 的倍数恰好是这个素数要判一下,a 等于 1 的时候也要判一下

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
#define kuaidian ios::sync_with_stdio(0);

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 7, maxd = 1e5 + 7;
const ll mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;

bool p[maxn];
vector<ll> prim;
bool pp[maxd];

void init() {
memset(p, 1, sizeof p);
for(int i = 4; i < maxn; i += 2)
p[i] = 0;
p[0] = p[1] = 0;
prim.push_back(2);
for(int i = 3; i < maxn; i += 2) {
if(p[i]) {
prim.push_back(i);
for(int j = i+i; j < maxn; j += i)
p[j] = 0;
}
}
}

int main() {
kuaidian;

init();
int T; cin >> T;
for(int tt = 1; tt <= T; ++tt) {
int a, b, ans = 0;
cin >> a >> b;
cout << "Case " << tt << ": " ;
int l_ = 0, r_ = b-a;
memset(pp, 1, sizeof pp);
for(int i = 0; prim[i]*prim[i] <= b && i < prim.size(); ++i) {
ll j = (a/prim[i] * prim[i]) + ( a%prim[i] == 0 ? 0 : prim[i] );
if(j < maxn && p[j]) j += prim[i];
for( ; j <= b; j += prim[i]) {
pp[j-a] = 0;
}
}
for(int i = 0; i <= r_; ++i)
if(pp[i]) ans++;
if(a == 1) ans--;
cout << ans << endl;
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: