#include <iostream>
#include <vector>
using namespace std;
int main() {
// Optymalizacja operacji wejścia/wyjścia (niezbędna przy n = 1 000 000)
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
if (!(cin >> n)) return 0;
// Powielamy tablicę, aby z łatwością symulować cykliczne przesunięcia (tzw. trick z tablicą 2n)
vector<int> a(2 * n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
a[i + n] = a[i];
}
// depth będzie przechowywać ile pereł wzbudzi zachwyt, jeśli zaczniemy oglądanie od indeksu i
vector<int> depth(2 * n, 0);
vector<int> st; // stos będzie trzymał indeksy, by łatwo znaleźć "następny większy element"
st.reserve(2 * n);
int max_depth = 0;
// Idziemy od końca do początku, wyliczając wszystko w jednym przejściu
for (int i = 2 * n - 1; i >= 0; --i) {
// Usuwamy ze stosu elementy, które nie są ściśle większe od a[i],
// ponieważ w przypadku analizy od a[i] w prawo, to a[i] będzie "zasłaniać" wszystkie mniejsze (i równe)
while (!st.empty() && a[st.back()] <= a[i]) {
st.pop_back();
}
// Jeśli stos jest pusty, to nie ma po prawej nic silnie większego -> ciąg "zachwytów" tu się kończy
if (st.empty()) {
depth[i] = 1;
} else {
// W przeciwnym razie element a[i] wzbudza zachwyt i dorzuca się do wyniku pierwszego większego od niego
depth[i] = depth[st.back()] + 1;
}
// Dodajemy aktualny indeks na stos
st.push_back(i);
// Zapisujemy największą głębokość osiągniętą przez perły na oryginalnych pozycjach [0, n-1]
if (i < n) {
if (depth[i] > max_depth) {
max_depth = depth[i];
}
}
}
// Wypisanie maksymalnej wartości k
cout << max_depth << "\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 | #include <iostream> #include <vector> using namespace std; int main() { // Optymalizacja operacji wejścia/wyjścia (niezbędna przy n = 1 000 000) ios_base::sync_with_stdio(false); cin.tie(NULL); int n; if (!(cin >> n)) return 0; // Powielamy tablicę, aby z łatwością symulować cykliczne przesunięcia (tzw. trick z tablicą 2n) vector<int> a(2 * n); for (int i = 0; i < n; ++i) { cin >> a[i]; a[i + n] = a[i]; } // depth będzie przechowywać ile pereł wzbudzi zachwyt, jeśli zaczniemy oglądanie od indeksu i vector<int> depth(2 * n, 0); vector<int> st; // stos będzie trzymał indeksy, by łatwo znaleźć "następny większy element" st.reserve(2 * n); int max_depth = 0; // Idziemy od końca do początku, wyliczając wszystko w jednym przejściu for (int i = 2 * n - 1; i >= 0; --i) { // Usuwamy ze stosu elementy, które nie są ściśle większe od a[i], // ponieważ w przypadku analizy od a[i] w prawo, to a[i] będzie "zasłaniać" wszystkie mniejsze (i równe) while (!st.empty() && a[st.back()] <= a[i]) { st.pop_back(); } // Jeśli stos jest pusty, to nie ma po prawej nic silnie większego -> ciąg "zachwytów" tu się kończy if (st.empty()) { depth[i] = 1; } else { // W przeciwnym razie element a[i] wzbudza zachwyt i dorzuca się do wyniku pierwszego większego od niego depth[i] = depth[st.back()] + 1; } // Dodajemy aktualny indeks na stos st.push_back(i); // Zapisujemy największą głębokość osiągniętą przez perły na oryginalnych pozycjach [0, n-1] if (i < n) { if (depth[i] > max_depth) { max_depth = depth[i]; } } } // Wypisanie maksymalnej wartości k cout << max_depth << "\n"; return 0; } |
English