#include using namespace std; typedef long long int TLL; class CIntervalMax { public: CIntervalMax ( vector & data ) : m_Array ( data ), m_BlockSize ( std::sqrt ( data . size () ) + 1 ), m_Maxs ( ) { for ( size_t i = 0; i < m_Array . size (); i += m_BlockSize ) { size_t en = std::min ( i + m_BlockSize, m_Array . size () ); TLL localMax = 0; for ( size_t st = i; st < en; st ++ ) localMax = max ( localMax, m_Array[st] ); m_Maxs . push_back ( localMax ); } #ifdef CHS cout << "size = " << m_Maxs . size () << endl; for ( TLL & xMax : m_Maxs ) cout << xMax << " "; cout << endl; #endif } TLL FindMax ( size_t st, size_t en ) { TLL rmq = 0; for ( ; st % m_BlockSize != 0 && st < en; st ++ ) rmq = max ( rmq, m_Array[st] ); while ( st + m_BlockSize <= en ) { size_t stBlock = st / m_BlockSize; rmq = max ( rmq, m_Maxs[stBlock] ); st += m_BlockSize; } for ( ; st < en; st ++ ) rmq = max ( rmq, m_Array[st] ); return rmq; } private: vector & m_Array; size_t m_BlockSize; vector m_Maxs; }; class CIntervalMaxNaive { public: CIntervalMaxNaive ( vector & data ) : m_Array ( data ) { } TLL FindMax ( size_t st, size_t en ) { return *max_element ( m_Array . begin () + st, m_Array . begin () + en ); } private: vector & m_Array; }; int main ( int argc, char * argv [] ) { #ifdef CHS vector test1 = { 1 }; CIntervalMax x1 ( test1 ); assert ( x1 . FindMax ( 0, 1 ) == 1 ); vector test2 = { 1, 2, 3, 4, 5 }; CIntervalMax x2 ( test2 ); assert ( x2 . FindMax ( 0, 5 ) == 5 ); assert ( x2 . FindMax ( 1, 2 ) == 2 ); assert ( x2 . FindMax ( 1, 3 ) == 3 ); assert ( x2 . FindMax ( 4, 5 ) == 5 ); vector test3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; CIntervalMax x3 ( test3 ); assert ( x3 . FindMax ( 5, 7 ) == 7 ); assert ( x3 . FindMax ( 8, 9 ) == 9 ); vector random ( 100 ); srand ( time ( NULL ) ); for ( size_t i = 0; i < random . size (); i ++ ) random[i] = rand () % 100; CIntervalMax m1 ( random ); CIntervalMaxNaive m2 ( random ); for ( size_t i = 0; i < random . size (); i ++ ) for ( size_t j = i + 1; j <= random . size (); j ++ ) { cout << "testing " << i << ", " << j << endl; TLL resM1 = m1 . FindMax ( i, j ); TLL resM2 = m2 . FindMax ( i, j ); if ( resM1 != resM2 ) { bool first = true; cout << "["; for ( TLL x : random ) if ( first ) { cout << x; first = false; } else cout << ", " << x; cout << "]" << endl; cout << "mismatch max(" << i << ", " << j << ") - m1 = " << resM1 << ", m2 = " << resM2 << endl; assert ( 0 ); } } #endif ios::sync_with_stdio ( 0 ); TLL n; map > heightsMap; vector heights; cin >> n; for ( TLL i = 0; i < n; i ++ ) { TLL x; cin >> x; heightsMap[x] . push_back ( i ); heights . push_back ( x ); } #ifdef CHS for ( const auto & entry : heightsMap ) { cout << entry . first << " => " << "["; bool first = true; for ( const auto & x : entry . second ) if ( first ) { cout << x; first = false; } else cout << ", " << x; cout << "]" << endl; } #endif CIntervalMax m ( heights ); TLL totalLength = 0; // all bridges for ( const auto & mapEntry : heightsMap ) { TLL height = mapEntry . first; const vector & elems = mapEntry . second; for ( size_t i = 1; i < elems . size (); i ++ ) if ( height >= m . FindMax ( elems[i - 1], elems[i] + 1 ) ) totalLength += elems[i] - elems[i-1] - 1; } cout << totalLength << endl; return ( 0 ); }