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
#include <bits/stdc++.h>
#define F first
#define S second
#define pii pair<long long,long long>
using namespace std;
using ll = long long;
using ld = long double;

constexpr int SIZE = 2e6+6;
constexpr int BASE = 1<<20;

int tree[2*BASE];
int tab[SIZE];
vector<int> bn[SIZE];
bool take[SIZE];

void ADD(int a, int b, int v){
    a += BASE-1;
    b += BASE+1;

    while (a != b-1){
        if (a%2==0) tree[a+1] = max(tree[a+1], v);
        if (b%2==1) tree[b-1] = max(tree[b-1], v);
        a /= 2;
        b /= 2;
    }
}

int QUERY(int i){
    i += BASE;
    int res = 0;
    while (i){
        res = max(res, tree[i]);
        i /= 2;
    }
    return res;
}

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

    int n;
    cin >> n;

    for (int i=1; i<=n; i++){
        cin >> tab[i];
        tab[i+n] = tab[i];
    }

    int res = 0;

    for (int i=1; i<=n; i++){
        int li = QUERY(tab[i]);

        if (li) bn[li].push_back(i);
        else {
            res ++;
            take[i] = 1;
        }
        ADD(1, tab[i], i);
    }

    int ans = res;

    for (int i=n+1; i<=2*n; i++){
        if (take[i-n]) res --;
        res += bn[i-n].size();
        for (int u:bn[i-n]) take[u] = 1;
        
        int li = QUERY(tab[i]);

        if (li+n > i) bn[li].push_back(i);
        else {
            res ++;
            take[i] = 1;
        }
        ADD(1, tab[i], i);

        ans = max(ans, res);
    }

    cout << ans;

return 0;}