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;
}
给定 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;
}
相关文章推荐
- LightOJ 1197 - Help Hanzo 【思维找素数 -> 区间素数筛选】
- LightOj 1197 - Help Hanzo(分段筛选法 求区间素数个数)
- LightOJ 1197 Help Hanzo 求区间内素数的个数
- Help Hanzo LightOJ - 1197
- LightOJ - 1197 Help Hanzo 素数筛
- 数学-B Help Hanzo (LightOJ - 1197 )
- LightOJ 1197 Help Hanzo 素数筛
- Help Hanzo lightof 1197 求一段区间内素数个数,[l,r] 在 [1,1e9] 范围内。r-l<=1e5; 采用和平常筛素数的方法。平移区间即可。
- lightOJ 1197 Help Hanzo 两阶段素数筛选
- Help Hanzo-LightOJ - 1197
- Help Hanzo LightOJ - 1197
- LightOJ 1197 区间素数筛(注意溢出的处理)
- LightOJ 1197 LightOJ 1197(大区间素数筛选)
- lightOJ 1197 Help Hanzo (区间找素数)
- LightOJ1197 - Help Hanzo(区间素数筛 + 模板)
- LightOJ 1197 Help Hanzo(区间素数筛)
- [大区间素数] lightoj 1197
- LightOJ 1197 Help Hanzo(区间素数筛选)
- LightOJ 1197 Help Hanzo(区间素数筛选)
- LightOj 1197 Help Hanzo (区间素数筛选)