#include <iostream>
#include <vector>
#include <utility>
// PART I: AVL Tree Implementation
class range_node;
class internal_node;
class leaf_node;
class range_node {
public:
range_node(int value, int height = 0, internal_node *parent = nullptr) : value{value}, height{height}, parent{parent} {}
range_node(int value, internal_node *parent = nullptr) : range_node{value, 0, parent} {}
virtual ~range_node() {}
virtual bool is_leaf() = 0;
virtual int get_start() = 0;
virtual int get_end() = 0;
int value;
int height;
internal_node *parent;
};
class internal_node : public range_node {
public:
internal_node(int start, int end, int value, internal_node *parent = nullptr)
: range_node{value, 1, parent}, start{start}, end{end} {}
~internal_node() {}
bool is_leaf() override { return false; }
int get_start() override { return start; }
int get_end() override { return end; }
int start, end;
range_node *left{nullptr};
range_node *right{nullptr};
};
class leaf_node : public range_node {
public:
leaf_node(int key, int value, internal_node *parent = nullptr) : range_node{value, parent}, key{key} {}
~leaf_node() {}
bool is_leaf() override { return true; }
int get_start() override { return key; }
int get_end() override { return key; }
int key;
};
class range_tree {
public:
~range_tree() { free(root); root = nullptr; }
int max() {
range_node *curr = root;
while (!curr->is_leaf()) {
curr = dynamic_cast<internal_node*>(curr)->right;
}
return curr->get_end();
}
void insert(int key, int value) {
if (!root) {
insert_root(key, value); return;
}
if (root && !root->right) {
insert_root_child(key, value); return;
}
auto leaf = get_leaf(key, value);
if (key == leaf->key) {
update_values(value, leaf); return;
}
internal_node *new_node = insert_new_leaf(key, value, leaf);
update_tree(new_node->parent, new_node);
}
int count(int key) {
return count(key, root) - 1;
}
std::vector<int> to_vector() {
std::vector<int> output;
traversal(output, root);
return output;
}
private:
void insert_root(int key, int value) {
root = new internal_node{key, key, value + 1};
root->left = new leaf_node{key, value + 1, root};
}
void insert_root_child(int key, int value) {
if (key < root->start) {
root->right = root->left;
root->left = new leaf_node{key, value + 1, root};
root->start = key;
root->value = (value + 1) * root->right->value;
return;
} else if (key > root->start) {
root->right = new leaf_node{key, value + 1, root};
root->end = key;
root->value = (value + 1) * root->left->value;
} else {
root->left->value += value;
root->value += value;
}
}
leaf_node* get_leaf(int key, int value) {
range_node *curr_node = root;
internal_node *curr = nullptr;
while (!curr_node->is_leaf()) {
curr = dynamic_cast<internal_node*>(curr_node);
if (key <= curr->left->get_end())
curr_node = curr->left;
else
curr_node = curr->right;
}
return dynamic_cast<leaf_node*>(curr_node);
}
void update_values(int value, leaf_node *leaf) {
leaf->value += value;
auto p = leaf->parent;
while (!p) {
p->value = p->left->value * p->right->value;
p = p->parent;
}
}
internal_node* insert_new_leaf(int key, int value, leaf_node *leaf) {
internal_node *new_node;
if (key > leaf->key) {
new_node = new internal_node{leaf->key, key, (value + 1) * leaf->value};
new_node->left = leaf;
new_node->right = new leaf_node{key, value + 1, new_node};
} else {
new_node = new internal_node{key, leaf->key, (value + 1) * leaf->value};
new_node->left = new leaf_node{key, value + 1, new_node};
new_node->right = leaf;
}
new_node->parent = leaf->parent;
leaf->parent = new_node;
if (new_node->parent->left == leaf) {
new_node->parent->left = new_node;
} else {
new_node->parent->right = new_node;
}
return new_node;
}
void update_tree(internal_node *curr, internal_node *new_node) {
internal_node *parent;
bool is_left;
while (curr) {
update_node(curr);
parent = curr->parent;
is_left = parent ? (parent->left == curr) : false;
curr = rebalance(curr, new_node);
if (!parent) {
root = curr;
root->parent = nullptr;
} else {
if (is_left) parent->left = curr;
else parent->right = curr;
curr->parent = parent;
}
curr = parent;
}
}
internal_node* rebalance(internal_node *curr, internal_node *new_node) {
int balance = curr->left->height - curr->right->height;
if (balance > 1) {
curr = left_left_case(curr, new_node);
curr = left_right_case(curr, new_node);
}
if (balance < -1) {
curr = right_right_case(curr, new_node);
curr = right_left_case(curr, new_node);
}
return curr;
}
internal_node* left_left_case(internal_node *curr, internal_node *new_node) {
internal_node *prev = dynamic_cast<internal_node*>(curr->left);
if (prev) {
internal_node *temp = dynamic_cast<internal_node*>(prev->left);
if (temp && new_node->start >= temp->start && new_node->end <= temp->end) {
return rotate_right(curr, prev);
}
}
return curr;
}
internal_node* left_right_case(internal_node *curr, internal_node *new_node) {
internal_node *prev = dynamic_cast<internal_node*>(curr->left);
if (prev) {
internal_node *temp = dynamic_cast<internal_node*>(prev->right);
if (temp && new_node->start >= temp->start && new_node->end <= temp->end) {
prev = rotate_left(prev, temp);
return rotate_right(curr, prev);
}
}
return curr;
}
internal_node* right_right_case(internal_node *curr, internal_node *new_node) {
internal_node *prev = dynamic_cast<internal_node*>(curr->right);
if (prev) {
internal_node *temp = dynamic_cast<internal_node*>(prev->right);
if (temp && new_node->start >= temp->start && new_node->end <= temp->end) {
return rotate_left(curr, prev);
}
}
return curr;
}
internal_node* right_left_case(internal_node *curr, internal_node *new_node) {
internal_node *prev = dynamic_cast<internal_node*>(curr->right);
if (prev) {
internal_node *temp = dynamic_cast<internal_node*>(prev->left);
if (temp && new_node->start >= temp->start && new_node->end <= temp->end) {
prev = rotate_right(prev, temp);
return rotate_left(curr, prev);
}
}
return curr;
}
internal_node* rotate_right(internal_node *curr, internal_node *prev) {
curr->left = prev->right;
prev->right = curr;
curr->parent = prev;
curr->left->parent = curr;
update_node(curr);
update_node(prev);
return prev;
}
internal_node* rotate_left(internal_node *curr, internal_node *prev) {
curr->right = prev->left;
prev->left = curr;
curr->parent = prev;
curr->right->parent = curr;
update_node(curr);
update_node(prev);
return prev;
}
void update_node(internal_node *p) {
p->start = p->left->get_start();
p->end = p->right->get_end();
p->value = p->left->value * p->right->value;
p->height = std::max(p->left->height, p->right->height) + 1;
}
int count(int key, range_node *node) {
if (!node) return 1;
if (node->is_leaf()) {
auto leaf = dynamic_cast<leaf_node*>(node);
if (key >= leaf->key) {
return leaf->value;
}
return 1;
}
auto internal = dynamic_cast<internal_node*>(node);
if (key < internal->right->get_start()) {
return count(key, internal->left);
}
if (key < internal->right->get_end()) {
return internal->left->value * count(key, internal->right);
}
return internal->value;
}
void traversal(std::vector<int> &output, range_node *node) {
if (!node) return;
if (node->is_leaf()) {
auto leaf = dynamic_cast<leaf_node*>(node);
for (int i = 0; i < leaf->value-1; i++)
output.push_back(leaf->key);
return;
}
auto p = dynamic_cast<internal_node*>(node);
traversal(output, p->left);
traversal(output, p->right);
}
void free(range_node *node) {
if (!node) return;
auto internal = dynamic_cast<internal_node*>(node);
if (internal) {
free(internal->left);
free(internal->right);
}
delete node;
}
internal_node *root{nullptr};
};
// PART II: Solution
typedef std::vector<std::pair<int,int>> pair_array;
pair_array make_pair_sequence(const std::vector<int> &numbers) {
pair_array arr;
for (int i = 0; i < numbers.size(); i++) {
if (i == 0) {
arr.push_back(std::make_pair(numbers[i], 1));
} else if (arr[arr.size()-1].first != numbers[i]) {
arr.push_back(std::make_pair(numbers[i], 1));
} else {
arr[arr.size()-1].second++;
}
}
return arr;
}
int decreasing_sequence_last_index(const pair_array &arr) {
int index = 0;
while (index < arr.size()-1 &&
arr[index].first > arr[index+1].first) {
index++;
}
return index;
}
int increasing_sequence_last_index(const pair_array &arr) {
int index = 0;
while (index < arr.size()-1 &&
arr[index].first < arr[index+1].first) {
index++;
}
return index;
}
int solution_sort(const std::vector<int> &numbers, bool debug) {
pair_array arr = make_pair_sequence(numbers);
if (arr.size() < 2) {
return 0;
}
range_tree tree;
int count = 0;
int last_index = decreasing_sequence_last_index(arr);
if (last_index > 0) {
tree.insert(arr[0].first, arr[0].second);
for (int i = 1; i <= last_index; i++) {
count += arr[i].second;
tree.insert(arr[i].first, arr[i].second);
}
}
if (last_index == 0) {
last_index = increasing_sequence_last_index(arr);
for (int i = 0; i <= last_index; i++) {
tree.insert(arr[i].first, arr[i].second);
}
}
for (int i = last_index+1; i < arr.size(); i++) {
if (arr[i].first < tree.max()) {
count += arr[i].second;
count += tree.count(arr[i].first);
tree.insert(arr[i].first, arr[i].second);
}
}
if (debug) {
std::vector<int> output = tree.to_vector();
for (auto e : output) std::cout << e << " ";
std::cout << "\n";
}
return count;
}
int main() {
int size; std::cin >> size;
std::vector<int> numbers(size);
for (int i = 0; i < size; i++) std::cin >> numbers[i];
int count = solution_sort(numbers, true);
std::cout << count << std::endl;
}