#include <vector>
#include <numeric>
#include <algorithm>
#include <random>
#include <cmath>
#include <set>
// Declare the interactor function
long long collisions(std::vector<long long> x);
namespace {
// Helper to find all divisors of val that are strictly greater than limit
std::vector<long long> get_divisors(long long val, long long limit) {
std::vector<long long> divs;
for (long long i = 1; i * i <= val; ++i) {
if (val % i == 0) {
if (i > limit) divs.push_back(i);
if (val / i > limit && val / i != i) divs.push_back(val / i);
}
}
return divs; // Order doesn't strictly matter, but smaller first is usually better for finding minimal n
}
// Check if a candidate n is correct
bool check_n(long long n) {
if (n <= 0) return false;
std::vector<long long> q = {1, n + 1};
return collisions(q) > 0;
}
}
int hack() {
// --- Phase 1: Efficient check for small N ---
const int SMALL_LIMIT = 2500;
std::vector<long long> small_q(SMALL_LIMIT);
std::iota(small_q.begin(), small_q.end(), 1);
if (collisions(small_q) > 0) {
// Binary search for the exact boundary
int low = 2, high = SMALL_LIMIT;
int ans = high;
while (low <= high) {
int mid = low + (high - low) / 2;
std::vector<long long> q(mid);
std::iota(q.begin(), q.end(), 1);
if (collisions(q) > 0) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans - 1;
}
// --- Phase 2: Large N with Birthday Attack ---
// Use fixed seed for reproducibility and valid logic
std::mt19937_64 rng(123456789);
// Range limited to 2*10^10 to ensure fast factorization
std::uniform_int_distribution<long long> dist(1, 20000000000LL);
// K=52000 gives ~74% success rate for n=10^9.
// Cost analysis: 52k (init) + ~52k (isolation) = ~104k. Fits < 110k budget.
int K = 52000;
while (true) {
std::vector<long long> current_set;
current_set.reserve(K);
std::set<long long> distinct_check; // Use set to ensure distinctness quickly
while (current_set.size() < K) {
long long val = dist(rng);
if (distinct_check.insert(val).second) {
current_set.push_back(val);
}
}
if (collisions(current_set) > 0) {
// Collision found, isolate the pair
while (true) {
// Base case: small enough set to brute force
if (current_set.size() <= 6) {
// Check all pairs in the small set
for (size_t i = 0; i < current_set.size(); ++i) {
for (size_t j = i + 1; j < current_set.size(); ++j) {
long long diff = std::abs(current_set[i] - current_set[j]);
std::vector<long long> cands = get_divisors(diff, SMALL_LIMIT);
for (long long cand : cands) {
if (check_n(cand)) return (int)cand;
}
}
}
// If we failed here (unlikely but possible if collision vanished due to some logic error),
// break to retry outer loop
break;
}
int sz = current_set.size();
int mid = sz / 2;
std::vector<long long> left_part(current_set.begin(), current_set.begin() + mid);
std::vector<long long> right_part(current_set.begin() + mid, current_set.end());
if (collisions(left_part) > 0) {
current_set = left_part;
} else if (collisions(right_part) > 0) {
current_set = right_part;
} else {
// Crossing collision. Shuffle and retry split.
std::shuffle(current_set.begin(), current_set.end(), rng);
}
}
}
// If no collision in initial set, loop repeats with a fresh set.
}
return -1;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |