func_code_string: #include <bits/stdc++.h>   using namespace std;   class SegmentTree {    private:     int n;     vector<int> st;     int left(int p) { return (p << 1); }     int right(int p) { return (p << 1) + 1; }     int parent(int p) { return (p >> 1); }     void build(int p, int L, int R) {       if (L == R)         st[p] = A[L];       else {         build(left(p), L, (L + R) / 2);         build(right(p), (L + R) / 2 + 1, R);         int p1 = st[left(p)], p2 = st[right(p)];         st[p] = p1 + p2;       }     }     int rsq(int p, int L, int R, int i, int j) {       if (i > R || j < L) return 0;       if (i <= L && R <= j) return st[p];       int p1 = rsq(left(p), L, (L + R) / 2, i, j);       int p2 = rsq(right(p), (L + R) / 2 + 1, R, i, j);       return p1 + p2;     }       public:     vector<int> A;     SegmentTree() {}     SegmentTree(const vector<int> &v) {       A = v;       n = (int)A.size();       st.assign(4 * n, 0);       build(1, 0, n - 1);     }     int query(int i, int j) { return rsq(1, 0, n - 1, i, j); }     void update(int i, int j, int a) {       A[i] = a;       int L = 0, R = n - 1, p = 1;       while (L < R) {         int mid = (L + R) / 2;         if (i <= mid) {           R = mid;           p = left(p);         } else {           L = mid + 1;           p = right(p);         }       }       st[p] = a;       while (p = parent(p)) {         int p1 = st[left(p)], p2 = st[right(p)];         st[p] = p1 + p2;       }     }   };   int a[123456];   int L[123456];   int R[123456];   vector<int> isOn(123456, 1);   int main() {     ios::sync_with_stdio(0);     cin.tie(0);     cout.tie(0);     int n;     cin >> n;     for (int i = 0; i < n; i++) cin >> a[i];     SegmentTree st(isOn);     vector<int> v;     for (int i = 1; i < n; i++) {       L[i] = i - 1;       R[i] = i + 1;       if (a[i] < a[i - 1]) v.push_back(i);     }     int cnt = 0;     while (v.size() > 0) {       for (int ID : v) {         st.update(ID, ID, 0);       }       vector<int> _new;       for (int ID : v) {         int isOk1 = st.query(R[ID], R[ID]);         int isOk2 = st.query(L[ID], L[ID]);         if (isOk1 && isOk2) {           R[L[ID]] = R[ID];           L[R[ID]] = L[ID];           if (R[ID] < n && a[R[ID]] < a[L[ID]]) {             _new.push_back(R[ID]);           }           continue;         }         if (R[ID] < n) {           int I = R[ID];           if (isOk1) {             int lo = 0, hi = I - 1, mid;             while (hi - lo > 5) {               mid = (lo + hi) / 2;               int foo = st.query(mid, I - 1);               if (foo > 1) {                 lo = mid + 1;               } else if (foo == 0) {                 hi = mid - 1;               } else {                 assert(foo == 1);                 lo = mid;               }             }             int idx = 0;             for (int i = hi; i >= lo; i--) {               if (st.query(i, I - 1) == 1) {                 idx = i;                 break;               }             }             L[I] = idx;             if (a[idx] > a[I]) _new.push_back(I);           }         }         int I = L[ID];         if (isOk2) {           int lo = I + 1, hi = n, mid;           while (hi - lo > 5) {             mid = (lo + hi) / 2;             int foo = st.query(I + 1, mid);             if (foo > 1) {               hi = mid - 1;             } else if (foo == 0) {               lo = mid + 1;             } else {               assert(foo == 1);               hi = mid;             }           }           int idx = n;           for (int i = lo; i <= hi; i++) {             if (st.query(I + 1, i) == 1) {               idx = i;               break;             }           }           R[I] = idx;           if (idx < n && a[idx] < a[I]) _new.push_back(idx);         }       }       v.clear();       v = _new;       assert(is_sorted(v.begin(), v.end()));       auto it = unique(v.begin(), v.end());       v.resize(distance(v.begin(), it));       cnt++;     }     cout << cnt <<   n ;     return 0;   }   