#include <bits/stdc++.h> using namespace std; // {{{ Fast IO #define g getchar_unlocked template<class T> inline void getint(T &num) { int ch; int isNgtv = 0; num = 0; for (ch = g(); !isdigit(ch) && ch != '-'; ch = g()); if (ch == '-') isNgtv = 1, ch = g(); for ( ; isdigit(ch); ch = g()) num = (num << 3) + (num << 1) + (T)(ch - 48); if (isNgtv) num = -num; } #undef g // }}} const int N = 5e5 + 5; const int INF = 1e9; #define left alskjdalskdj #define right laskdjaslkdj struct Node { int l = -1, r = -1; int val = 0; }; int last; Node node[12000500]; int n; int a[N]; vector<int> left, right; pair<int,pair<int, int>> risan; int precom[N]; int roots[N]; inline int query(int root1, int root2, int l, int r, int ql, int qr) { if (l > qr || r < ql || node[root1].val == node[root2].val) return 0; if (l >= ql && r <= qr) return node[root1].val - node[root2].val; int mid = (l + r) >> 1; return query(node[root1].l, node[root2].l, l, mid, ql, qr) + query(node[root1].r, node[root2].r, mid + 1, r, ql, qr); } inline bool cek(int mid, int optL, int optR) { if (precom[mid] == -1 || precom[mid] > optR) return false; int ret = max(precom[mid], optL); return a[left[mid]] > a[right[ret]]; } inline void solve(int l, int r, int optL, int optR) { //printf("%d %d %d %d %d %d\n",l,r,optL,optR,1,1); if (l > r) return; int mid = (l + r) >> 1; int ll = mid, rr = mid; if (!cek(mid, optL, optR)) { for (int i = 1;; ++i) { if (mid + i > r && mid - i < l) return; rr++; if (mid + i <= r && cek(mid + i, optL, optR)) { mid = rr; break; } ll--; if (mid - i >= l && cek(mid - i, optL, optR)) { mid = ll; break; } } } int ret = max(precom[mid], optL); int optMid = optR; int optMidValue = -INF; for (int i = ret; i <= optR; ++i) { if (a[left[mid]] <= a[right[i]]) break; //printf("%d %d %d %d\n",mid,i,left[mid],right[i]); //if (left[mid] < right[i]) { //int val = query(left[mid], right[i], a[right[i]], a[left[mid]]); //int val = roots[right[i] + 1]->query(a[right[i]], a[left[mid]]) - roots[left[mid]]->query(a[right[i]], a[left[mid]]); //printf("%d %d %d %d\n",a[left[mid]],a[right[i]], left[mid],right[i]); int val = query(roots[right[i] + 1], roots[left[mid]], 0, n - 1, a[right[i]], a[left[mid]]); if (optMidValue < val) { optMid = i; optMidValue = val; } //} } //printf("%d %d %d %d %d %d\n",l,r,optL,optR,optMid,optMidValue); risan = max(risan, make_pair(optMidValue, make_pair(-left[mid], -right[optMid]))); solve(l, ll - 1, optL, optMid); solve(rr + 1, r, optMid, optR); } inline int build(int l, int r) { int cur = last++; if (l != r) { int mid = (l + r) >> 1; node[cur].l = build(l, mid); node[cur].r = build(mid + 1, r); } return cur; } inline int update(int prev, int l, int r, int qp) { int cur = last++; if (l == r) { node[cur].val = node[prev].val + 1; } else { int mid = (l + r) >> 1; if (qp <= mid) { node[cur].l = update(node[prev].l, l, mid, qp); node[cur].r = node[prev].r; } else { node[cur].l = node[prev].l; node[cur].r = update(node[prev].r, mid + 1, r, qp); } node[cur].val = node[node[cur].l].val + node[node[cur].r].val; } return cur; } int main() { getint(n); roots[0] = build(0, n - 1); for (int i = 0; i < n; i++) { getint(a[i]); --a[i]; roots[i + 1] = update(roots[i], 0, n - 1, a[i]); } risan = make_pair(-INF, make_pair(0,0)); int lst = -INF; for (int i = 0; i < n; ++i) { if (a[i] > lst) { lst = a[i]; left.push_back(i); } } lst = INF; for (int i = n - 1; i >= 0; --i) { if (a[i] < lst) { lst = a[i]; right.push_back(i); } } reverse(right.begin(), right.end()); for (int i = 0; i < (int)left.size(); ++i) { precom[i] = -1; int L = 0; int R = (int)right.size() - 1; while (L <= R) { int M = (L + R) >> 1; if (left[i] < right[M]) { precom[i] = M; R = M - 1; } else { L = M + 1; } } } solve(0, left.size() - 1, 0, right.size() - 1); if (risan.first == -INF) puts("Cool Array"); else printf("%d %d\n",-risan.second.first+1, -risan.second.second+1); return 0; }