#include<stdio.h> #include<stdlib.h> struct node { int key; struct node *left; struct node *right; int height; int size; }; int max(int a, int b); int height(struct node *N) { if (N == NULL) return 0; return N->height; } // A utility function to size of the tree of rooted with N int size(struct node *N) { if (N == NULL) return 0; return N->size; } // A utility function to get maximum of two integers int max(int a, int b) { return (a > b)? a : b; } /* Helper function that allocates a new node with the given key and NULL left and right pointers. */ struct node* newNode(int key) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->key = key; node->left = NULL; node->right = NULL; node->height = 1; // new node is initially added at leaf node->size = 1; return(node); } // A utility function to right rotate subtree rooted with y struct node *rightRotate(struct node *y) { struct node *x = y->left; struct node *T2 = x->right; // Perform rotation x->right = y; y->left = T2; // Update heights y->height = max(height(y->left), height(y->right))+1; x->height = max(height(x->left), height(x->right))+1; // Update sizes y->size = size(y->left) + size(y->right) + 1; x->size = size(x->left) + size(x->right) + 1; // Return new root return x; } // A utility function to left rotate subtree rooted with x struct node *leftRotate(struct node *x) { struct node *y = x->right; struct node *T2 = y->left; // Perform rotation y->left = x; x->right = T2; // Update heights x->height = max(height(x->left), height(x->right))+1; y->height = max(height(y->left), height(y->right))+1; // Update sizes x->size = size(x->left) + size(x->right) + 1; y->size = size(y->left) + size(y->right) + 1; // Return new root return y; } // Get Balance factor of node N int getBalance(struct node *N) { if (N == NULL) return 0; return height(N->left) - height(N->right); } struct node* insert(struct node* node, int key,int *count1) { /* 1. Perform the normal BST rotation */ if (node == NULL) return(newNode(key)); if (key < node->key) { node->left = insert(node->left, key,count1); // count1 = *count1 + size(node->right) + 1; } else { if(key > node->key) { node->right = insert(node->right, key,count1); *count1 = *count1 + size(node->left) + 1; } else node->right = insert(node->right, key,count1); } node->height = max(height(node->left), height(node->right)) + 1; node->size = size(node->left) + size(node->right) + 1; int balance = getBalance(node); if (balance > 1 && key < node->left->key) return rightRotate(node); // Right Right Case if (balance < -1 && key > node->right->key) return leftRotate(node); // Left Right Case if (balance > 1 && key > node->left->key) { node->left = leftRotate(node->left); return rightRotate(node); } if (balance < -1 && key < node->right->key) { node->right = rightRotate(node->right); return leftRotate(node); } return node; } struct node* insert1(struct node* node, int key, int *count) { if (node == NULL) return(newNode(key)); if (key < node->key) { node->left = insert1(node->left, key, count); *count = *count + size(node->right) + 1; } else { /* if(key > node->key) { node->right = insert(node->right, key, count,count1); *count1 = *count1 + size(node->left) + 1; } else */ node->right = insert1(node->right, key,count); } node->height = max(height(node->left), height(node->right)) + 1; node->size = size(node->left) + size(node->right) + 1; int balance = getBalance(node); if (balance > 1 && key < node->left->key) return rightRotate(node); // Right Right Case if (balance < -1 && key > node->right->key) return leftRotate(node); // Left Right Case if (balance > 1 && key > node->left->key) { node->left = leftRotate(node->left); return rightRotate(node); } if (balance < -1 && key < node->right->key) { node->right = rightRotate(node->right); return leftRotate(node); } return node; } void constructLowerArray (int arr[],int arr1[] ,int countSmaller[],int countHigh[], int n) { int i, j; struct node *root = NULL; struct node *root1=NULL; for (i = 0; i < n; i++) { countSmaller[i] = 0; countHigh[i]=0; } for (i = 0; i <n; i++) { root = insert(root, arr[i],&countSmaller[n-1-i]); root1= insert1(root1,arr1[i],&countHigh[i]); } } void printArray(int arr[], int size) { int i; printf("\n"); for (i=0; i < size; i++) printf("%d ", arr[i]); printf("\n"); } void find_max(int low[],int high[],int n) { int i,j,k,l; int tempL[2][n],tempH[2][n]; int max=low[0],maxIdx=1; tempL[0][0]=max; tempL[1][0]=maxIdx; for(i=1;i<n;i++){ if(low[i]>max){ max=low[i]; maxIdx=i+1; } tempL[0][i]=max; tempL[1][i]=maxIdx; } max=high[n-1],maxIdx=n; tempH[0][n-1]=max; tempH[1][n-1]=maxIdx; for(i=n-2;i>=0;i--){ if(high[i]>=max){ max=high[i]; maxIdx=i+1; } tempH[0][i]=max; tempH[1][i]=maxIdx; } max=tempL[0][0]+tempH[0][1]; k=tempL[1][0]; l=tempH[1][1]; for(i=1;i<n-1;i++){ if(max<tempL[0][i]+tempH[0][i+1]){ max=tempL[0][i]+tempH[0][i+1]; k=tempL[1][i]; l=tempH[1][i+1]; } } if(max==0) { printf("Cool Array\n"); return; } else { printf("%d %d",k,l); } } void reverse(int arr[],int arr1[],int n) { int low=0,i; for(i=n-1;i>=0;i--) { arr[low++]=arr1[i]; } } int main() { int n; scanf("%d",&n); int arr[n],i,arr1[n]; for(i=0;i<n;i++) scanf("%d",&arr1[i]); reverse(arr,arr1,n); // int arr[] = {2, 4, 3, 6, 5, 1}; // int arr1[]={1,5,6,3,4,2}; int *low = (int *)malloc(sizeof(int)*n); int *high = (int *)malloc(sizeof(int)*n); constructLowerArray(arr,arr1 ,low,high ,n); // constructHigherArray(arr, high, n); // printArray(low, n); // printArray(high, n); find_max(low,high,n); return 0; }