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
#include <bits/stdc++.h>
using namespace std;

int a[2000007];
int cut[2000007];
int tree[2097152];  // drzewo punkt-przedział na wartościach

void insert(int i, int w) {
    // cerr << "wpisuje " << i << " " << w << "\n";
    tree[i] = w;
    i /= 2;
    while (i > 0) {
        tree[i] = max(tree[2 * i], tree[2 * i + 1]);
        i /= 2;
    }
}

int read(int i, int first, int last, int left, int right) {
    if (first > right || last < left) {
        // cerr << first << " " << last << " out of bounds " << left << " " << right << "\n";
        return -1;
    }
    if (first >= left && last <= right) {
        // cerr << "czytam " << i << " " << tree[i] << "\n";
        return tree[i];
    }
    return max(read(2 * i, first, (first + last) / 2, left, right),
               read(2 * i + 1, (first + last) / 2 + 1, last, left, right));
}

struct adapter {
    bool operator()(const pair<int, int> &x, const pair<int, int> &y) {
        if (x.first > y.first) {
            return true;
        } else {
            return false;
        }
    }
};

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    
    int n;
    cin >> n;

    int maxa = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        maxa = max(a[i], maxa);
        a[n + i] = a[i];
    }

    int m = 1;
    while (m < maxa) {
        m *= 2;
    }

    // cerr << "maxa = " << maxa << " m = " << m << "\n";

    for (int i = 1; i < 2 * m; i++) {
        tree[i] = -1;
    }

    for (int i = 0; i < 2 * n; i++) {
        // cerr << "tab[" << i << "] = " << tab[i] << "\n";
        // cerr << "CZYTAJ " << tab[i] + m - 1 << " " <<  maxa + m - 1 << "\n";
        cut[i] = read(1, m, 2 * m - 1, a[i] + m - 1, maxa + m - 1);
        insert(a[i] + m - 1, i);

        // cerr << cut[i] << " ";
    }
    // cerr << "\n";

    // set<pair<int, int>> mniejsze;
    int mniejsze = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, adapter> wieksze; // kolejka priorytetowa sortuje od najmniejszych

    for (int i = 0; i < n; i++) {
        if (cut[i] < 0) {
            mniejsze++;
            // mniejsze.insert({cut[i], i});
        } else {
            wieksze.push({cut[i], i});
        }
    }
    // int wyn = mniejsze.size();
    int wyn = mniejsze;

    // cerr << "mniejsze od 0: ";
    // for (auto& [x, y] : mniejsze) cerr << "cut[" << y << "] = " << x << ", ";
    // cerr << "\n";

    for (int i = 1; i < n; i++) {  // teraz i - nowy początek
        if (cut[i - 1] < i - 1) {
            mniejsze--;
        }
        else {
            // zostaje w większych
        }

        // przerzucam
        while (!wieksze.empty() && wieksze.top().first < i) {
            if (wieksze.top().second >= i) {
                mniejsze++;
            }
            wieksze.pop();
        }

        if (cut[i + n - 1] < i) {
            // cerr << "cut[" << i + n - 1 << "] = " << cut[i + n - 1] << " < " << i << "\n"; 
            // mniejsze.insert({cut[i + n - 1], i + n - 1});
            mniejsze++;
        } else {
            // cerr << "cut[" << i + n - 1 << "] = " << cut[i + n - 1] << " >= " << i << "\n"; 
            wieksze.push({cut[i + n - 1], i + n - 1});
        }

        // cerr << "mniejsze od " << i << ": ";
        // for (auto& [x, y] : mniejsze) cerr << "cut[" << y << "] = " << x << ", ";
        // cerr << "\n";

        // wyn = max(wyn, (int)(mniejsze.size()));
        wyn = max(wyn, mniejsze);
    }

    cout << wyn << "\n";
}