#include <stdio.h> #include <vector> #include <set> #define MAXN 500005 #define MAX(a, b) (((a) > (b))?(a):(b)) #define MIN(a, b) (((a) < (b))?(a):(b)) #define DEBUG 0 using namespace std; struct Comp { bool operator()(int a, int b) { return a > b; } }; long long nrinv; int n, perm[MAXN], pozperm[MAXN], nsr, ai[4 * MAXN], lazy[4 * MAXN], sol, aib[MAXN], solx, soly; bool specialLeft[MAXN], specialRight[MAXN]; vector<int> st, vsl; pair<int, int> vsr[MAXN]; set<int, Comp> s; int binarySearchVal(pair<int, int> v[], int val) { // last i with v[i].second < val if(v[1].second > val) return 0; if(v[nsr].second < val) return nsr; int l = 1, r = nsr, mid; while(l < r) { mid = (l + r) >> 1; if(v[mid].second < val) l = mid + 1; else r = mid - 1; } while(l > nsr || v[l].second >= val) --l; return l; } int binarySearchPoz(pair<int, int> v[], int poz) { //first i with v[i].first > poz if(v[1].first > poz) return 1; if(v[nsr].first <= poz) return nsr + 1; int l = 1, r = nsr, mid; while(l < r) { mid = (l + r) >> 1; if(v[mid].first <= poz) l = mid + 1; else r = mid - 1; } while(r < 1 || v[r].first <= poz) ++r; return r; } pair<int, int> intervalsIntersection(int l1, int r1, int l2, int r2) { if(r1 < l1 || r2 < l2) return make_pair(1, 0); return make_pair(MAX(l1, l2), MIN(r1, r2)); } void lazyUpdate(int node) { if(lazy[node] == 0) return; lazy[2 * node] += lazy[node]; lazy[2 * node + 1] += lazy[node]; ai[2 * node] += lazy[node]; ai[2 * node + 1] += lazy[node]; lazy[node] = 0; } void query_ai(int node, int l, int r, int &lq, int &rq, int &ans) { if(lq <= l && r <= rq) { ans = MAX(ans, ai[node]); return; } lazyUpdate(node); int mid = (l + r) >> 1; if(lq <= mid) query_ai(2 * node, l, mid, lq, rq, ans); if(mid + 1 <= rq) query_ai(2 * node + 1, mid + 1, r, lq, rq, ans); } void update_ai(int node, int l, int r, int &lq, int &rq, int val) { if(lq <= l && r <= rq) { ai[node] += val; lazy[node] += val; return; } lazyUpdate(node); int mid = (l + r) >> 1; if(lq <= mid) update_ai(2 * node, l, mid, lq, rq, val); if(mid + 1 <= rq) update_ai(2 * node + 1, mid + 1, r, lq, rq, val); ai[node] = MAX(ai[2 * node], ai[2 * node + 1]); } pair<int, int> getInterval(int val) { int l1 = 1, r1 = binarySearchVal(vsr, val); int l2 = binarySearchPoz(vsr, pozperm[val]), r2 = nsr; return intervalsIntersection(l1, r1, l2, r2); } void ai_delete(int val) { pair<int, int> lr = getInterval(val); if(lr.first <= lr.second) update_ai(1, 1, nsr, lr.first, lr.second, -1); } void ai_add(int val) { pair<int, int> lr = getInterval(val); if(lr.first <= lr.second) update_ai(1, 1, nsr, lr.first, lr.second, 1); } void update_aib(int pos, int val) { while(pos <= n) { aib[pos] += val; pos += (pos & (-pos)); } } int query_aib(int pos) { int ans = 0; while(pos) { ans += aib[pos]; pos -= (pos & (-pos)); } return ans; } int main() { //freopen("in", "r", stdin); scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &perm[i]); pozperm[perm[i]] = i; } int i; for(i = 2; i <= n && perm[i - 1] < perm[i]; i++); if(i > n) { printf("Cool Array\n"); return 0; } for(int i = 1; i <= n; i++) { while(!st.empty() && st.back() < perm[i]) st.pop_back(); specialLeft[i] = st.empty(); st.push_back(perm[i]); } st.clear(); for(int i = n; i >= 1; i--) { while(!st.empty() && st.back() > perm[i]) st.pop_back(); specialRight[i] = st.empty(); st.push_back(perm[i]); } if(DEBUG) { printf("specialLeft:\n"); for(int i = 1; i <= n; i++) printf("%d ", specialLeft[i]); printf("\n\n"); printf("specialRight:\n"); for(int i = 1; i <= n; i++) printf("%d ", specialRight[i]); printf("\n\n"); } for(int i = 1; i <= n; i++) if(specialRight[i]) vsr[++nsr] = make_pair(i, perm[i]); for(int i = 1; i <= n; i++) if(specialLeft[i]) vsl.push_back(perm[i]); for(int i = n; i >= 1; i--) { if(perm[i] == vsl.back()) { vsl.pop_back(); /*int l1 = 1, r1 = binarySearchVal(vsr, perm[i]); // val < perm[i] int l2 = binarySearchPoz(vsr, i), r2 = nsr; // poz > i pair<int, int> lr = intervalsIntersection(l1, r1, l2, r2);*/ pair<int, int> lr = getInterval(perm[i]); if(lr.first <= lr.second) { int possol = 0; query_ai(1, 1, nsr, lr.first, lr.second, possol); if(possol >= sol) { sol = possol; solx = i; } } if(!vsl.empty()) { int x = vsl.back(); while(!s.empty() && *s.begin() >= x) { ai_delete(*s.begin()); s.erase(s.begin()); } } } else { if(perm[i] > vsl.back()) continue; ai_add(perm[i]); s.insert(perm[i]); } } int sol = -1, tot = 0; for(int i = solx + 1; i <= n; i++) { if(perm[i] < perm[solx]) { int possol = tot - query_aib(perm[i]); if(possol > sol) { soly = i; sol = possol; } update_aib(perm[i], 1); ++tot; } } printf("%d %d\n", solx, soly); return 0; }