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
| #include<bits/stdc++.h> using namespace std; #ifdef LOCAL #define debug(...) fprintf(stdout, ##__VA_ARGS__) #define debag(...) fprintf(stderr, ##__VA_ARGS__) #else #define debug(...) void(0) #define debag(...) void(0) #endif #define int long long inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+ (x<<3)+(ch^48);ch=getchar();}return x*f;} #define Z(x) (x)*(x) #define pb push_back #define fi first #define se second
#define N 1000010 int n, m, i, j, k, T; int a[N], x, y, s1, s2; int lmx[N], rmx[N], lst, ans;
int find_L(int i) { int l = 1, r = lmx[i], mid; while(l < r) { mid = (l + r) >> 1; if(a[lmx[mid]] >= a[i]) r = mid; else l = mid + 1; } return l; }
int find_R(int i) { int l = rmx[i], r = n, mid; while(l < r) { mid = (l + r + 1) >> 1; if(a[rmx[mid]] <= a[i]) l = mid; else r = mid - 1; } return r; }
namespace Scan { struct Segment_tree { #define ls (k << 1) #define rs (k << 1 | 1) #define mid ((l + r) >> 1) int tag[N << 2], mx[N << 2]; void push_down(int k) { tag[ls] += tag[k]; tag[rs] += tag[k]; mx[ls] += tag[k]; mx[rs] += tag[k]; tag[k] = 0; } void add(int k, int l, int r, int x, int y, int z) { if(l >= x && r <= y) return tag[k] += z, mx[k] += z, void(); push_down(k); if(x <= mid) add(ls, l, mid, x, y, z); if(y >= mid + 1) add(rs, mid + 1, r, x, y, z); mx[k] = max(mx[ls], mx[rs]); } #undef ls #undef rs #undef mid }Seg; struct node { int l, r, v; }; vector<node>G[N]; void insert(int lx, int ly, int rx, int ry) {
debug("%lld %lld %lld %lld\n", lx, ly, rx, ry); G[rx].pb({lx, ly, 1}); G[ry + 1].pb({lx, ly, -1}); } int run() { int i, ans = 0; for(i = 1; i <= n; ++i) { for(auto t : G[i]) { Seg.add(1, 1, n, t.l, t.r, t.v); } ans = max(ans, Seg.mx[1]); } return ans; } }
signed main() { freopen("inverse.in", "r", stdin); freopen("inverse.out", "w", stdout);
n = read(); for(i = 1; i <= n; ++i) a[i] = read(); for(i = 1, lst = 0; i <= n; ++i) { if(a[i] > lst) lst = a[i], lmx[i] = i; else lmx[i] = lmx[i - 1]; } for(i = n, lst = 1e9; i >= 1; --i) { if(a[i] < lst) lst = a[i], rmx[i] = i; else rmx[i] = rmx[i + 1]; } for(i = 1; i <= n; ++i) debug("%lld ", lmx[i]); debug("\n"); for(i = 1; i <= n; ++i) debug("%lld ", rmx[i]); debug("\n"); for(i = 1; i <= n; ++i) { int L = find_L(i), R = find_R(i); Scan :: insert(L, lmx[i], rmx[i], R); } ans = Scan :: run(); printf("%lld", 2 * ans - 3); return 0; }
|