#include <cstdio>
#include <vector>
#include <cmath>
#ifdef LOCAL
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#else
#define dbg(...)
#endif
using namespace std;
constexpr long long MAX_SQRT = 320000; // max prime we can find when factorizing
bool is_prime(const long long n, const vector<long long>& lower_primes) {
const long long sqrt1 = sqrt(n);
// start with j=2 because we only check 6n-1, 6n+1, which are never divisible by 2 and 3
for (unsigned long j = 2; j < lower_primes.size(); ++j) {
if (lower_primes[j] > sqrt1) {
break;
}
if (n % lower_primes[j] == 0) {
return false;
}
}
return true;
}
vector<long long> compute_primes(const long long max_n) {
vector<long long> primes;
primes.push_back(2);
primes.push_back(3);
for (int i = 6; i <= max_n; i += 6) {
long long candidate_1 = i - 1;
if (is_prime(candidate_1, primes)) {
primes.push_back(candidate_1);
}
long long candidate_2 = i + 1;
if (is_prime(candidate_2, primes)) {
primes.push_back(candidate_2);
}
}
return primes;
}
vector<long long> factorize(long long n, vector<long long>& primes) {
dbg("Factorizing %lld\n", n);
vector<long long> fact;
for (const long long prime: primes) {
while (n % prime == 0) {
fact.push_back(prime);
n /= prime;
}
if (n == 1) break;
}
if (n != 1) fact.push_back(n);
dbg("Found %lu prime factors\n", fact.size());
return fact;
}
bool solution_possible(const long long k, const vector<long long>& plarza) {
vector<long long> wavesizes;
long long totalwaves = 0;
const unsigned long plen = plarza.size();
for (unsigned long i = 0; i < plen; ++i) {
if (static_cast<long long>(i) >= k) {
// end old wave if we're far enough
dbg("wave of size %lld started at %lld has no effect now\n", (wavesizes[i-k]), i-k);
totalwaves -= wavesizes[i-k];
}
dbg("current value is %lld, and guaranteed waves total to %lld\n", plarza[i], totalwaves);
if (plarza[i] < totalwaves) {
dbg("FAIL: guaranteed waves are too high\n");
return false;
}
if (i + k <= plen) {
// start a new wave if we can fit it
dbg("starting wave of size %lld at position %lu\n", (plarza[i] - totalwaves), i);
wavesizes.push_back(plarza[i] - totalwaves);
totalwaves += (plarza[i] - totalwaves);
} else {
// if we can't start a new wave, completion must be exact
if (plarza[i] != totalwaves) {
dbg("FAIL: stuff still remaining, but can't start a new wave\n");
return false;
}
}
}
return true;
}
int main() {
int n;
vector<long long> plarza;
long long totalsum = 0LL;
long long max_a = 0LL; // minimum number of waves
long long first_desc = -1;
long long last_asc = 0;
vector<long long> primes = compute_primes(MAX_SQRT);
scanf("%d", &n);
long long prevy = -1;
for (int i = 0; i < n; ++i) {
long long y;
scanf("%lld", &y);
plarza.push_back(y);
if (y > prevy) last_asc = i;
if (first_desc == -1 && y < prevy) first_desc = i;
if (y > max_a) {
max_a = y;
}
totalsum += y;
prevy = y;
}
if (first_desc == -1 && last_asc == 0) {
// constant val
printf("%d\n", n);
return 0;
}
// this can be -1 if sequence is non-desc / non-asc, but not constant.
// we will just return "1" then
long long max_size = min(first_desc, (n - last_asc));
vector<long long> sum_factors = factorize(totalsum, primes);
dbg("Max wave size due to ascending/descending values is %lld\n", max_size);
dbg("Total sum is: %lld\n", totalsum);
dbg("Factors of total sum:\n");
for (auto& factor: sum_factors) {
dbg("%lld ", factor);
}
dbg("\n");
for (long long i = max_size; i >= 2; --i) {
if (totalsum % i != 0) continue;
dbg("--- Checking possibility of %lld solution...\n", i);
if (solution_possible(i, plarza)) {
printf("%lld\n", i);
return 0;
}
}
printf("1\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 145 146 147 148 149 150 | #include <cstdio> #include <vector> #include <cmath> #ifdef LOCAL #define dbg(...) fprintf(stderr, __VA_ARGS__) #else #define dbg(...) #endif using namespace std; constexpr long long MAX_SQRT = 320000; // max prime we can find when factorizing bool is_prime(const long long n, const vector<long long>& lower_primes) { const long long sqrt1 = sqrt(n); // start with j=2 because we only check 6n-1, 6n+1, which are never divisible by 2 and 3 for (unsigned long j = 2; j < lower_primes.size(); ++j) { if (lower_primes[j] > sqrt1) { break; } if (n % lower_primes[j] == 0) { return false; } } return true; } vector<long long> compute_primes(const long long max_n) { vector<long long> primes; primes.push_back(2); primes.push_back(3); for (int i = 6; i <= max_n; i += 6) { long long candidate_1 = i - 1; if (is_prime(candidate_1, primes)) { primes.push_back(candidate_1); } long long candidate_2 = i + 1; if (is_prime(candidate_2, primes)) { primes.push_back(candidate_2); } } return primes; } vector<long long> factorize(long long n, vector<long long>& primes) { dbg("Factorizing %lld\n", n); vector<long long> fact; for (const long long prime: primes) { while (n % prime == 0) { fact.push_back(prime); n /= prime; } if (n == 1) break; } if (n != 1) fact.push_back(n); dbg("Found %lu prime factors\n", fact.size()); return fact; } bool solution_possible(const long long k, const vector<long long>& plarza) { vector<long long> wavesizes; long long totalwaves = 0; const unsigned long plen = plarza.size(); for (unsigned long i = 0; i < plen; ++i) { if (static_cast<long long>(i) >= k) { // end old wave if we're far enough dbg("wave of size %lld started at %lld has no effect now\n", (wavesizes[i-k]), i-k); totalwaves -= wavesizes[i-k]; } dbg("current value is %lld, and guaranteed waves total to %lld\n", plarza[i], totalwaves); if (plarza[i] < totalwaves) { dbg("FAIL: guaranteed waves are too high\n"); return false; } if (i + k <= plen) { // start a new wave if we can fit it dbg("starting wave of size %lld at position %lu\n", (plarza[i] - totalwaves), i); wavesizes.push_back(plarza[i] - totalwaves); totalwaves += (plarza[i] - totalwaves); } else { // if we can't start a new wave, completion must be exact if (plarza[i] != totalwaves) { dbg("FAIL: stuff still remaining, but can't start a new wave\n"); return false; } } } return true; } int main() { int n; vector<long long> plarza; long long totalsum = 0LL; long long max_a = 0LL; // minimum number of waves long long first_desc = -1; long long last_asc = 0; vector<long long> primes = compute_primes(MAX_SQRT); scanf("%d", &n); long long prevy = -1; for (int i = 0; i < n; ++i) { long long y; scanf("%lld", &y); plarza.push_back(y); if (y > prevy) last_asc = i; if (first_desc == -1 && y < prevy) first_desc = i; if (y > max_a) { max_a = y; } totalsum += y; prevy = y; } if (first_desc == -1 && last_asc == 0) { // constant val printf("%d\n", n); return 0; } // this can be -1 if sequence is non-desc / non-asc, but not constant. // we will just return "1" then long long max_size = min(first_desc, (n - last_asc)); vector<long long> sum_factors = factorize(totalsum, primes); dbg("Max wave size due to ascending/descending values is %lld\n", max_size); dbg("Total sum is: %lld\n", totalsum); dbg("Factors of total sum:\n"); for (auto& factor: sum_factors) { dbg("%lld ", factor); } dbg("\n"); for (long long i = max_size; i >= 2; --i) { if (totalsum % i != 0) continue; dbg("--- Checking possibility of %lld solution...\n", i); if (solution_possible(i, plarza)) { printf("%lld\n", i); return 0; } } printf("1\n"); return 0; } |
English