# Luogu1835 素数密度_NOI导刊2011提高（04

先说 Miller-Rabin

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cstdio>
using namespace std;

typedef long long ll;
const int MAX_SIZ = 2000005;

int lef, rig, ans;
int prime[3] = {2, 7, 61};
bool not_prime[MAX_SIZ];

inline int fast_pow(int bot, int top, int mod) {
register int ret = 1;
while (top) {
if (top & 1) ret = 1ll * ret * bot % mod;
top >>= 1;
bot = 1ll * bot * bot % mod;
}
return ret;
}
inline bool dvd_chk(int bot, int top, int mod) {
register int tmp;
while (!(top & 1)) {
tmp = fast_pow(bot, top, mod);
if (tmp == 1) top >>= 1;
else if (tmp == mod - 1) return true;
else return false;
}
return true;
}
inline bool Test(int a) {
if (a <= 1) return false;
if (a == 2) return true;
if (!(a & 1)) return false;
for (int i = 0; i < 3; ++i) {
if (prime[i] == a) return true;
if (fast_pow(prime[i], a - 1, a) != 1) return false;
if (!dvd_chk(prime[i], a - 1, a)) return false;
}
return true;
}

int main() {
scanf("%d%d", &lef, &rig);
register ll tmp;
for (ll i = lef; i <= rig; ++i) {
if (not_prime[i - lef] || i == 1) continue;
if (Test(i)) {
++ans;
tmp = (2ll * i);
while (tmp <= rig) {
not_prime[tmp - lef] = true;
tmp += tmp;
}
} else not_prime[i - lef] = true;
}
printf("%d\n", ans);
return 0;
}


然后是正解的做法

2147483647 的 mindiv 也不过才 46341

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <cmath>
using namespace std;

typedef long long ll;
const int MAX_SQRT = 65536, MAX_N = 1000005;

int lef, rig, tot_prime, ans;
int prime[MAX_SQRT];
bool not_prime[MAX_SQRT], GG[MAX_N];

inline void get_prime(int top) {
not_prime[1] = true;
for (ll i = 2; i <= top; ++i) {
if (!not_prime[i]) prime[++tot_prime] = i;
for (int j = 1; j <= tot_prime && 1ll * i * prime[j] <= top; ++j) {
not_prime[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
return;
}

int main() {
get_prime(46341);
scanf("%d%d", &lef, &rig);
for (int i = 1; i <= tot_prime && prime[i] <= rig; ++i) {
for (ll j = ll(ceil(double(lef) / prime[i])) * prime[i]; j <= rig; j += prime[i]) {
if (j != prime[i]) GG[j - lef] = true;
}
}
for (ll i = lef; i <= rig; ++i) ans += (!GG[i - lef]);
printf("%d\n", ans);
return 0;
}


posted @ 2018-11-05 13:29  AWordThatWeDefine  阅读(137)  评论(0编辑  收藏  举报