#pragma comment(linker, "/STACK:100000000") #define _CRT_SECURE_NO_WARNINGS #pragma GCC optimize("O500") #include <algorithm> #include <iostream> #include <memory.h> #include <cstdlib> #include <complex> #include <sstream> #include <cstring> #include <fstream> #include <vector> #include <cstdio> #include <string> #include <bitset> #include <queue> #include <stack> #include <ctime> #include <cmath> #include <map> #include <set> using namespace std; typedef unsigned long long ull; typedef complex < double > cd; typedef long double ld; typedef long long ll; template < class T > void read(T &x) { char c, mi = 0; while(c = getchar(), c <= 32); if(c == '-') mi = 1, x = 0; else if(c < 48 || c > 57) return void(x = c); else x = c - 48; while(c = getchar(), c > 32) x = 10 * x + c - 48; if(mi == 1) x = -x; } template < class T > void read(T &x, T &y) { read(x); read(y); } template < class T > void read(T &x, T &y, T &z) { read(x, y); read(z); } template < class T > void reada(T *a, int n) { for(int i = 0; i < n; ++i) read(a[i]); } template < class T > void write(T x) { static char s[20]; char pt = 0, mi = (x < 0); if(mi == 1) x = -x; while(!pt || x > 0) { s[++pt] = (char)(x % 10 + '0'); x /= 10; } if(mi == 1) putchar('-'); while(pt > 0) putchar(s[pt--]); } template < class T > void write(T x, T y) { write(x); putchar(' '); write(y); } template < class T > void write(T x, T y, T z) { write(x, y); putchar(' '); write(z); } template < class T > void writeln(T x) { write(x); puts(""); } template < class T > void writea(T *a, int n) { for(int i = 0; i < n; ++i) { write(a[i]); putchar(i + 1 == n ? '\n' : ' '); } } template < class T > T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template < class T > T lcm(T a, T b) { return a / gcd(a, b) * b; } template < class T > T qpom(T a, T b, T mod = 1000000007) { T r = 1; while(b > 0) { if(b & 1) r = r * a % mod; a = a * a % mod; b /= 2; } return r; } template < class T > T qpow(T a, T b) { T r = 1; while(b > 0) { if(b & 1) r *= a; a *= a; b /= 2; } return r; } template < class T > T imin(T a, T b) { return a < b ? a : b; } template < class T > T imax(T a, T b) { return a > b ? a : b; } template < class T > inline void rmin(T &a, const T &b) { if(a > b) a = b; } template < class T > inline void rmax(T &a, const T &b) { if(a < b) a = b; } template < class T > T sqr(const T &a) { return a * a; } #define debug(x) cout << #x << "=" << x #define debuge(x, c) cout << #x << "=" << x << (c) #define debugn(x) cout << #x << "=" << x << "\n" #ifndef DEBUG #define eprintf(...) fprintf(stderr, "%s -> ", string(to_string((long long)__LINE__)).c_str()), fprintf(stderr, __VA_ARGS__), fflush(stderr) #else #define eprintf(...) #endif #define ppb pop_back #define pb push_back #define mp make_pair #define fs first #define sd second #define inf 1000000007 #define nmax 100010 #define mmax 300010 #define eps 1e-9 const int N = 5e5 + 10; struct Node { int l, r, sum; } t[60 * N]; int n, p[N]; int roots[N], pt; int f[N]; int build(int l, int r) { int ret = ++pt; if (l != r) { t[ret].l = build(l, (l + r) / 2); t[ret].r = build((l + r) / 2 + 1, r); } return ret; } int get(int v, int L, int R, int l, int r) { if (L == l && r == R) { return t[v].sum; } int M = (L + R) / 2; if (r <= M) { return get(t[v].l, L, M, l, r); } if (l > M) { return get(t[v].r, M + 1, R, l, r); } return get(t[v].l, L, M, l, M) + get(t[v].r, M + 1, R, M + 1, r); } int upd(int v, int l, int r, int pos, int val) { int ret = ++pt; if (l != r) { int m = (l + r) >> 1; if (pos <= m) { t[ret].l = upd(t[v].l, l, m, pos, val); t[ret].r = t[v].r; } else { t[ret].r = upd(t[v].r, m + 1, r, pos, val); t[ret].l = t[v].l; } t[ret].sum = t[t[ret].l].sum + t[t[ret].r].sum; } else { t[ret].sum = val; } return ret; } int foo(int p[], int n, int a, int b) { if (a > b) { swap(a, b); } if (a == b) { return -1000000000; } // cout << a << ' ' << b << endl; // cout << get(roots[a], 0, n + 1, p[a] + 1, n + 1) << endl; // cout << get(roots[b], 0, n + 1, p[a] + 1, n + 1) << endl; // cout << get(roots[a], 0, n + 1, p[b] + 1, n + 1) << endl; // cout << get(roots[b], 0, n + 1, p[b] + 1, n + 1) << endl; int ret = 0; ret -= get(roots[a - 1], 0, n + 1, p[a] + 1, n + 1); ret += get(roots[b - 1], 0, n + 1, p[a] + 1, n + 1); ret -= get(roots[b - 1], 0, n + 1, p[b] + 1, n + 1); ret += get(roots[a - 1], 0, n + 1, p[b] + 1, n + 1); return -ret; } long long cw(const pair < int, int > &a, const pair < int, int > &b, const pair < int, int > &c) { return 1LL * (a.first - b.first) * (c.second - b.second) - 1LL * (a.second - b.second) * (c.first - b.first); } vector < pair < int, int > > convex_hull(const vector < pair < int, int > > &v) { vector < pair < int, int > > up, dw, conv; up.reserve(v.size()); dw.reserve(v.size()); up.push_back(v[0]); dw.push_back(v[0]); for (int i = 0; i < (int)v.size(); ++i) { if (i == (int)v.size() - 1 || cw(v[0], v[i], v.back()) > 0) { while (up.size() >= 2 && !(cw(up[up.size() - 2], up[up.size() - 1], v[i]) > 0)) { up.pop_back(); } up.push_back(v[i]); } if (i == (int)v.size() - 1 || cw(v[0], v[i], v.back()) < 0) { while (dw.size() >= 2 && !(cw(dw[dw.size() - 2], dw[dw.size() - 1], v[i]) < 0)) { dw.pop_back(); } dw.push_back(v[i]); } } for (int i = 0; i < (int)up.size(); ++i) { conv.push_back(up[i]); } for (int i = (int)dw.size() - 2; i > 0; --i) { conv.push_back(dw[i]); } return conv; } int fi; pair < int, int > ret; bool DEBUG = false; void relax(int p[], int n, int i, int j) { if (i > j) { swap(i, j); } int val = foo(p, n, i, j); if (val > fi || val == fi && make_pair(i, j) < ret) { ret = make_pair(i, j); fi = val; } } pair < pair < int, int >, pair < int, int > > solve(int p[], int n) { bool ok = true; for (int i = 1; i <= n; ++i) { ok &= p[i] == i ? true : false; } if (ok == true) { puts("Cool Array"); exit(0); } roots[0] = build(0, n + 1); for (int i = 1; i <= n; ++i) { roots[i] = upd(roots[i - 1], 0, n + 1, p[i], 1); } vector < pair < int, int > > v, u; for (int i = 1; i <= n; ++i) { v.push_back(make_pair(i, p[i])); } u = convex_hull(v); // while(true); int size = (int)u.size(); // for (int i = 0; i < size; ++i) { // cout << u[i].first << ' ' << u[i].second << endl; // } pair < pair < int, int >, pair < int, int > > ret2; ret = make_pair(1000010, 1000010); fi = -1000000007; if (DEBUG == true) { if (n <= 3000) { for (int i = 1; i <= n; ++i) { for (int j = i + 1; j <= n; ++j) { if (p[i] > p[j]) { int temp = foo(p, n, i, j); if (temp > fi) { fi = temp; ret.first = i; ret.second = j; } } } } // cout << fi << endl; ret2.first = ret; fi = -1000000007; } } for (int i = 0; i < size; ++i) { u.push_back(u[i]); } for (int i = 0; i < size; ++i) { for (int j = i + 1; j < size; ++j) { relax(p, n, u[i].first, u[j].first); } } rotate(u.begin(), u.begin() + 1, u.begin() + size); for (int i = 0, j = 0; i < size; ++i) { j = max(j, i); while(j + 1 < size) { relax(p, n, u[i].first, u[j + 1].first); relax(p, n, u[i].first, u[j].first); if (foo(p, n, u[i].first, u[j + 1].first) >= foo(p, n, u[i].first, u[j].first)) { j += 1; } else { break; } } relax(p, n, u[i].first, u[j].first); // cout << u[i].first << ' ' << u[j].first << '\n'; } fi = -1000000007; for (int i = ret.first + 1; i <= n; ++i) { if (foo(p, n, ret.first, i) > fi) { fi = foo(p, n, ret.first, i); ret.second = i; } } fi = -1000000007; for (int i = 1; i < ret.second; ++i) { if (foo(p, n, i, ret.second) > fi) { fi = foo(p, n, i, ret.second); ret.first = i; } } ret2.second = ret; return ret2; } void test(int n) { DEBUG = true; for (int i = 1; i <= n; ++i) { p[i] = i; } int cnt = 0; do { if (++cnt == 1) { continue; } pair < pair < int, int >, pair < int, int > > temp = solve(p, n); if (temp.first != temp.second) { cout << "NIE" << '\n'; writea(p + 1, n); cout << temp.first.first << ' ' << temp.first.second << ' ' << temp.second.first << ' ' << temp.second.second << '\n'; while(true); } } while(next_permutation(p + 1, p + n + 1)); cout << "OK" << '\n'; exit(0); } int main() { // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); // freopen("sum.in", "r", stdin); freopen("sum.out", "w", stdout); // 6 // 1 3 2 5 4 6 // test(6); scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &p[i]); } pair < int, int > ans = solve(p, n).second; printf("%d %d\n", ans.first, ans.second); getchar(); getchar(); return 0; }