#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <ctime>
#include <vector>
#include <set>
#include <queue>
using namespace std;
const int64_t MOD = 10000008;
const int FORCE_SMALL_PRIMES = 128;
const int RANDOM_SAMPLE_SIZE = 256;
const int FORCE_INITIAL = 64;
const int FORCE_INITIAL_DELTA = 8;
const int MAX_FULL_SEARCH_Q = 4096;
const int PQUE_REBUILD_INTERVAL = 4096;
const int SIEVE_MAX = 10000;
int main () {
srand(time(0));
int n, q;
scanf("%d %d", &n, &q);
vector<int> primes;
vector<bool> is_prime(SIEVE_MAX, true);
is_prime[0] = false;
is_prime[1] = false;
for (int i = 2; i < SIEVE_MAX; ++i) {
if (is_prime[i]) {
primes.push_back(i);
int next = 2 * i;
while (next < SIEVE_MAX) {
is_prime[next] = false;
next += i;
}
}
}
vector<int> changes(q, 0);
for (int i = 0; i < q; ++i) {
scanf("%d", &changes[i]);
}
set<int> deltas;
if (q <= MAX_FULL_SEARCH_Q) {
for (int i = 0; i < q - 1; ++i) {
for (int j = i + 1; j < q; ++j) {
deltas.insert(abs(changes[j] - changes[i]));
}
}
}
else {
for (int i = 0; i < FORCE_INITIAL; ++i) {
for (int j = 1; j <= FORCE_INITIAL_DELTA; ++j) {
if (i + j >= q) {
continue;
}
deltas.insert(abs(changes[i + j] - changes[i]));
}
}
for (int i = 0; i < RANDOM_SAMPLE_SIZE; ++i) {
deltas.insert(abs(changes[rand() % q] - changes[rand() % q]));
}
}
set<int> primes_to_use;
for (int i = 0; i < FORCE_SMALL_PRIMES; ++i) {
primes_to_use.insert(primes[i]);
}
for (set<int>::iterator it = deltas.begin(); it != deltas.end(); it++) {
if (*it < 2) {
continue;
}
int test_div = 2;
bool found = false;
while (test_div * test_div <= *it) {
if ((*it % test_div == 0) && is_prime[test_div]) {
primes_to_use.insert(test_div);
found = true;
}
++test_div;
}
if (!found) {
primes_to_use.insert(*it);
}
}
vector<int> primes_filtered;
for (set<int>::iterator it = primes_to_use.begin(); it != primes_to_use.end(); it++) {
primes_filtered.push_back(*it);
}
priority_queue<pair<int, int64_t> > pque;
vector<vector<int> > counters;
for (int i = 0; i < primes_filtered.size(); ++i) {
counters.push_back(vector<int>(primes_filtered[i], 0));
}
vector<bool> enabled(n, false);
for (int i = 0; i < q; ++i) {
int x = changes[i];
if (!enabled[x]) {
enabled[x] = true;
for (int j = 0; j < primes_filtered.size(); ++j) {
int prime = primes_filtered[j];
int64_t key = ((int64_t)j) * MOD + (int64_t)(x % prime);
int cnt = ++counters[j][x % prime];
pque.push(make_pair(cnt, key));
}
}
else {
enabled[x] = false;
for (int j = 0; j < primes_filtered.size(); ++j) {
int prime = primes_filtered[j];
int64_t key = ((int64_t)j) * MOD + (int64_t)(x % prime);
int cnt = --counters[j][x % prime];
if (cnt) {
pque.push(make_pair(cnt, key));
}
}
}
if (i % PQUE_REBUILD_INTERVAL == PQUE_REBUILD_INTERVAL - 1) {
pque = priority_queue<pair<int, int64_t> >();
for (int j = 0; j < counters.size(); ++j) {
for (int k = 0; k < counters[j].size(); ++k) {
int val = counters[j][k];
if (val > 0) {
pque.push(make_pair(counters[j][k], ((int64_t)j) * MOD + (int64_t)k));
}
}
}
}
bool found = false;
while (!pque.empty()) {
pair<int, int64_t> item = pque.top();
if (counters[item.second / MOD][item.second % MOD] == item.first) {
printf("%d\n", item.first);
found = true;
break;
}
else {
pque.pop();
}
}
if (!found) {
printf("0\n");
}
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #include <cstdio> #include <cstdlib> #include <cstdint> #include <ctime> #include <vector> #include <set> #include <queue> using namespace std; const int64_t MOD = 10000008; const int FORCE_SMALL_PRIMES = 128; const int RANDOM_SAMPLE_SIZE = 256; const int FORCE_INITIAL = 64; const int FORCE_INITIAL_DELTA = 8; const int MAX_FULL_SEARCH_Q = 4096; const int PQUE_REBUILD_INTERVAL = 4096; const int SIEVE_MAX = 10000; int main () { srand(time(0)); int n, q; scanf("%d %d", &n, &q); vector<int> primes; vector<bool> is_prime(SIEVE_MAX, true); is_prime[0] = false; is_prime[1] = false; for (int i = 2; i < SIEVE_MAX; ++i) { if (is_prime[i]) { primes.push_back(i); int next = 2 * i; while (next < SIEVE_MAX) { is_prime[next] = false; next += i; } } } vector<int> changes(q, 0); for (int i = 0; i < q; ++i) { scanf("%d", &changes[i]); } set<int> deltas; if (q <= MAX_FULL_SEARCH_Q) { for (int i = 0; i < q - 1; ++i) { for (int j = i + 1; j < q; ++j) { deltas.insert(abs(changes[j] - changes[i])); } } } else { for (int i = 0; i < FORCE_INITIAL; ++i) { for (int j = 1; j <= FORCE_INITIAL_DELTA; ++j) { if (i + j >= q) { continue; } deltas.insert(abs(changes[i + j] - changes[i])); } } for (int i = 0; i < RANDOM_SAMPLE_SIZE; ++i) { deltas.insert(abs(changes[rand() % q] - changes[rand() % q])); } } set<int> primes_to_use; for (int i = 0; i < FORCE_SMALL_PRIMES; ++i) { primes_to_use.insert(primes[i]); } for (set<int>::iterator it = deltas.begin(); it != deltas.end(); it++) { if (*it < 2) { continue; } int test_div = 2; bool found = false; while (test_div * test_div <= *it) { if ((*it % test_div == 0) && is_prime[test_div]) { primes_to_use.insert(test_div); found = true; } ++test_div; } if (!found) { primes_to_use.insert(*it); } } vector<int> primes_filtered; for (set<int>::iterator it = primes_to_use.begin(); it != primes_to_use.end(); it++) { primes_filtered.push_back(*it); } priority_queue<pair<int, int64_t> > pque; vector<vector<int> > counters; for (int i = 0; i < primes_filtered.size(); ++i) { counters.push_back(vector<int>(primes_filtered[i], 0)); } vector<bool> enabled(n, false); for (int i = 0; i < q; ++i) { int x = changes[i]; if (!enabled[x]) { enabled[x] = true; for (int j = 0; j < primes_filtered.size(); ++j) { int prime = primes_filtered[j]; int64_t key = ((int64_t)j) * MOD + (int64_t)(x % prime); int cnt = ++counters[j][x % prime]; pque.push(make_pair(cnt, key)); } } else { enabled[x] = false; for (int j = 0; j < primes_filtered.size(); ++j) { int prime = primes_filtered[j]; int64_t key = ((int64_t)j) * MOD + (int64_t)(x % prime); int cnt = --counters[j][x % prime]; if (cnt) { pque.push(make_pair(cnt, key)); } } } if (i % PQUE_REBUILD_INTERVAL == PQUE_REBUILD_INTERVAL - 1) { pque = priority_queue<pair<int, int64_t> >(); for (int j = 0; j < counters.size(); ++j) { for (int k = 0; k < counters[j].size(); ++k) { int val = counters[j][k]; if (val > 0) { pque.push(make_pair(counters[j][k], ((int64_t)j) * MOD + (int64_t)k)); } } } } bool found = false; while (!pque.empty()) { pair<int, int64_t> item = pque.top(); if (counters[item.second / MOD][item.second % MOD] == item.first) { printf("%d\n", item.first); found = true; break; } else { pque.pop(); } } if (!found) { printf("0\n"); } } return 0; } |
English