/* 2026
* Maciej Szeptuch
*/
#include <cstdio>
#include <set>
#include <vector>
const int MAX_SIZE = 16777216;
const int MAX_EVENTS = 1048576;
int size;
int events;
int position;
int divider[MAX_SIZE];
int bucket[MAX_SIZE];
std::vector<int> primes;
std::set<int> positions;
std::set<std::pair<int, int>> bucket_sizes;
int jump = 2;
int main(void)
{
scanf("%d %d", &size, &events);
for(int j = 2; j < size; ++j)
{
if(divider[j])
continue;
primes.push_back(j);
divider[j] = j;
for(long long int q = 1LL * j * j; q < size; q += j)
divider[q] = j;
}
for(int e = 0; e < events; ++e)
{
scanf("%d", &position);
bool removed = false;
if(positions.contains(position))
{
positions.erase(position);
removed = true;
}
else
positions.insert(position);
if(positions.size() <= 2)
{
bucket_sizes.clear();
printf("%lu\n", positions.size());
continue;
}
int best = 2;
if(!bucket_sizes.empty())
{
int pos = position % jump;
bool largest = bucket_sizes.rbegin()->second == pos;
bucket_sizes.erase({bucket[pos], pos});
if(!removed)
++bucket[pos];
else
--bucket[pos];
bucket_sizes.insert({bucket[pos], pos});
if(largest && !removed)
{
printf("%d\n", bucket_sizes.rbegin()->first);
continue;
}
best = bucket_sizes.rbegin()->first;
}
for(int j: primes)
{
if(j > 2 * size / best)
break;
for(int p = 0; p < j; ++p)
bucket[p] = 0;
bucket_sizes.clear();
for(int p: positions)
{
int pos = p % j;
bucket_sizes.erase({bucket[pos], pos});
++bucket[pos];
bucket_sizes.insert({bucket[pos], pos});
if(best < bucket_sizes.rbegin()->first)
{
best = bucket_sizes.rbegin()->first;
jump = j;
}
}
}
for(int p = 0; p < jump; ++p)
bucket[p] = 0;
bucket_sizes.clear();
for(int p: positions)
++bucket[p % jump];
for(int p = 0; p < jump; ++p)
bucket_sizes.insert({bucket[p], p});
printf("%d\n", bucket_sizes.rbegin()->first);
}
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 | /* 2026 * Maciej Szeptuch */ #include <cstdio> #include <set> #include <vector> const int MAX_SIZE = 16777216; const int MAX_EVENTS = 1048576; int size; int events; int position; int divider[MAX_SIZE]; int bucket[MAX_SIZE]; std::vector<int> primes; std::set<int> positions; std::set<std::pair<int, int>> bucket_sizes; int jump = 2; int main(void) { scanf("%d %d", &size, &events); for(int j = 2; j < size; ++j) { if(divider[j]) continue; primes.push_back(j); divider[j] = j; for(long long int q = 1LL * j * j; q < size; q += j) divider[q] = j; } for(int e = 0; e < events; ++e) { scanf("%d", &position); bool removed = false; if(positions.contains(position)) { positions.erase(position); removed = true; } else positions.insert(position); if(positions.size() <= 2) { bucket_sizes.clear(); printf("%lu\n", positions.size()); continue; } int best = 2; if(!bucket_sizes.empty()) { int pos = position % jump; bool largest = bucket_sizes.rbegin()->second == pos; bucket_sizes.erase({bucket[pos], pos}); if(!removed) ++bucket[pos]; else --bucket[pos]; bucket_sizes.insert({bucket[pos], pos}); if(largest && !removed) { printf("%d\n", bucket_sizes.rbegin()->first); continue; } best = bucket_sizes.rbegin()->first; } for(int j: primes) { if(j > 2 * size / best) break; for(int p = 0; p < j; ++p) bucket[p] = 0; bucket_sizes.clear(); for(int p: positions) { int pos = p % j; bucket_sizes.erase({bucket[pos], pos}); ++bucket[pos]; bucket_sizes.insert({bucket[pos], pos}); if(best < bucket_sizes.rbegin()->first) { best = bucket_sizes.rbegin()->first; jump = j; } } } for(int p = 0; p < jump; ++p) bucket[p] = 0; bucket_sizes.clear(); for(int p: positions) ++bucket[p % jump]; for(int p = 0; p < jump; ++p) bucket_sizes.insert({bucket[p], p}); printf("%d\n", bucket_sizes.rbegin()->first); } return 0; } |
English