#pragma GCC optimize("O3,unroll-loops")
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
int n;
vector<long long> a;
vector<long long> c; // Tablica przechowująca liczbę fal STARTUJĄCYCH w danym indeksie
// Funkcja sprawdzająca w czasie O(N) czy da się ułożyć fale o szerokości k
bool check(int k) {
long long active_waves = 0; // Ile fal obecnie nakłada się na sprawdzany segment
// Resetujemy tablicę startów dla bieżącego testu k
fill(c.begin(), c.end(), 0);
for (int i = 0; i < n; ++i) {
// Jeśli jakaś fala skończyła się przed tym indeksem, odejmujemy ją od aktywnych
if (i >= k) {
active_waves -= c[i - k];
}
// Ile nowych fal musi się zacząć w tym indeksie, żeby dobić do a[i]
c[i] = a[i] - active_waves;
// Zapotrzebowanie nie może być ujemne
if (c[i] < 0) return false;
// Fale nie mogą zaczynać się tak późno, że wyjdą poza długość plaży
if (i > n - k && c[i] > 0) return false;
active_waves += c[i];
}
return true;
}
int main() {
// Odłączenie synchronizacji dla błyskawicznego I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);
if (!(cin >> n)) return 0;
a.resize(n);
c.resize(n);
long long total_sum = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
total_sum += a[i];
}
// Znajdowanie wszystkich dzielników total_sum, które są <= n
vector<int> divisors;
for (long long i = 1; i * i <= total_sum; ++i) {
if (total_sum % i == 0) {
if (i <= n) divisors.push_back(i);
long long pair_div = total_sum / i;
if (pair_div <= n && pair_div != i) divisors.push_back(pair_div);
}
}
// Sortowanie malejąco, aby zacząć sprawdzanie od największych k
sort(divisors.rbegin(), divisors.rend());
for (int k : divisors) {
if (check(k)) {
// Pierwsze pasujące k to nasz optymalny wynik!
cout << k << "\n";
break;
}
}
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 | #pragma GCC optimize("O3,unroll-loops") #include <iostream> #include <vector> #include <numeric> #include <algorithm> using namespace std; int n; vector<long long> a; vector<long long> c; // Tablica przechowująca liczbę fal STARTUJĄCYCH w danym indeksie // Funkcja sprawdzająca w czasie O(N) czy da się ułożyć fale o szerokości k bool check(int k) { long long active_waves = 0; // Ile fal obecnie nakłada się na sprawdzany segment // Resetujemy tablicę startów dla bieżącego testu k fill(c.begin(), c.end(), 0); for (int i = 0; i < n; ++i) { // Jeśli jakaś fala skończyła się przed tym indeksem, odejmujemy ją od aktywnych if (i >= k) { active_waves -= c[i - k]; } // Ile nowych fal musi się zacząć w tym indeksie, żeby dobić do a[i] c[i] = a[i] - active_waves; // Zapotrzebowanie nie może być ujemne if (c[i] < 0) return false; // Fale nie mogą zaczynać się tak późno, że wyjdą poza długość plaży if (i > n - k && c[i] > 0) return false; active_waves += c[i]; } return true; } int main() { // Odłączenie synchronizacji dla błyskawicznego I/O ios_base::sync_with_stdio(false); cin.tie(NULL); if (!(cin >> n)) return 0; a.resize(n); c.resize(n); long long total_sum = 0; for (int i = 0; i < n; ++i) { cin >> a[i]; total_sum += a[i]; } // Znajdowanie wszystkich dzielników total_sum, które są <= n vector<int> divisors; for (long long i = 1; i * i <= total_sum; ++i) { if (total_sum % i == 0) { if (i <= n) divisors.push_back(i); long long pair_div = total_sum / i; if (pair_div <= n && pair_div != i) divisors.push_back(pair_div); } } // Sortowanie malejąco, aby zacząć sprawdzanie od największych k sort(divisors.rbegin(), divisors.rend()); for (int k : divisors) { if (check(k)) { // Pierwsze pasujące k to nasz optymalny wynik! cout << k << "\n"; break; } } return 0; } |
English