乱搞做法重见天日。目前能过掉在数据范围内的所有已知数据。求更强的 hack,或证明该代码 hack 不掉。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using u64 = unsigned long long;
using u128 = __uint128_t;
static unsigned char p[50000005];
static unsigned char num[10000005];
inline u64 modmul(u64 a, u64 b, u64 mod) {
return (u128)a * b % mod;
}
inline u64 modpow(u64 a, u64 d, u64 mod) {
u64 r = 1;
while (d) {
if (d & 1) r = modmul(r, a, mod);
a = modmul(a, a, mod);
d >>= 1;
}
return r;
}
inline bool miller_rabin(u64 n) {
if (n < 2) return false;
for (u64 x : {2ull,3ull,5ull,7ull,11ull}) {
if (n == x) return true;
if (n % x == 0) return false;
}
u64 d = n - 1, s = 0;
while ((d & 1) == 0) { d >>= 1; ++s; }
auto check = [&](u64 a)->bool{
if (a % n == 0) return true;
u64 x = modpow(a, d, n);
if (x == 1 || x == n-1) return true;
for (u64 r = 1; r < s; ++r) {
x = modmul(x, x, n);
if (x == n-1) return true;
}
return false;
};
for (u64 a : {2ull,7ull,61ull}) {
if (a >= n) break;
if (!check(a)) return false;
}
return true;
}
inline bool isprime(int n) {
if (p[n] != 0) return p[n] == 2;
bool isp;
if (n <= 1) isp = false;
else if (n <= 3) isp = true;
else if ((n & 1) == 0) isp = false;
else isp = miller_rabin((u64)n);
p[n] = isp ? 2 : 1;
return isp;
}
int N, M;
int maxn = 0;
void dfs(int dep) {
if (dep < 0) return;
long long base = 1LL << dep;
int limit = (base==0) ? M : (int)(M / base);
if (limit < 3) {
dfs(dep - 1);
return;
}
for (int i = 3; i <= limit; i += 2) {
if (isprime(i)) {
long long prod = base * 1LL * i;
if (prod >= N && prod <= M) {
cout << dep + 1;
return;
} else if (prod > M) {
dfs(dep - 1);
return;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
const int threshold = 2097150;
cin >> N >> M;
int k = (int)floor(log2((double)M));
if (((1 << k) >= N)) {
cout << k;
return 0;
} else if ((M - N + 1) <= threshold) {
if (M >= 1) num[1] = 0;
if (M >= 2) {
isprime(2);
num[2] = 1;
}
for (int i = 3; i <= M; ++i) {
if ((i & 1) == 0) {
num[i] = num[2] + num[i >> 1];
continue;
}
if (isprime(i)) {
num[i] = 1;
continue;
}
if (i % 3 == 0) {
num[i] = num[3] + num[i / 3];
continue;
}
int lim = (int)floor(sqrt((double)i));
bool done = false;
for (int j = 5; j <= lim; j += 6) {
int a = j;
if (i % a == 0) {
num[i] = num[a] + num[i / a];
done = true;
break;
}
int b = j + 2;
if (b <= lim && i % b == 0) {
num[i] = num[b] + num[i / b];
done = true;
break;
}
}
if (!done) {
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0) {
num[i] = num[j] + num[i / j];
done = true;
break;
}
}
if (!done) {
num[i] = 1;
}
}
}
unsigned char best = 0;
for (int i = max(2, N); i <= M; ++i) {
if (num[i] > best) best = num[i];
}
cout << (int)best;
return 0;
} else {
dfs(k - 1);
return 0;
}
}
请不要在意我的逆天码风。