// https://szkopul.edu.pl/problemset/problem/LRxIzCCc5Nn4UvWV514zro4a/site/
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct Node {
int base; // Base value without deltas
int delta; // Lazy delta to propagate
int priority; // For Treap heap property
int size; // Size of the subtree
Node *left, *right;
Node(int val) : base(val), delta(0), priority(rand()), size(1), left(nullptr), right(nullptr) {}
};
class BalancedBST {
private:
Node* root;
int getSize(Node* node) { return node ? node->size : 0; }
void updateSize(Node* node) {
if (node) node->size = 1 + getSize(node->left) + getSize(node->right);
}
void propagate(Node* node) {
if (!node || node->delta == 0) return;
node->base += node->delta;
if (node->left) node->left->delta += node->delta;
if (node->right) node->right->delta += node->delta;
node->delta = 0;
}
void split(Node* root, int k, Node*& left, Node*& right) {
propagate(root);
if (!root) {
left = right = nullptr;
return;
}
int leftSize = getSize(root->left);
if (k <= leftSize) {
split(root->left, k, left, root->left);
right = root;
} else {
split(root->right, k - leftSize - 1, root->right, right);
left = root;
}
updateSize(root);
}
Node* merge(Node* left, Node* right) {
propagate(left);
propagate(right);
if (!left) return right;
if (!right) return left;
if (left->priority > right->priority) {
left->right = merge(left->right, right);
updateSize(left);
return left;
} else {
right->left = merge(left, right->left);
updateSize(right);
return right;
}
}
Node* insert(Node* node, int x) {
if (!node) return new Node(x);
propagate(node);
if (x <= node->base) {
node->left = insert(node->left, x);
if (node->left->priority > node->priority) {
Node* rotated = node->left;
propagate(rotated);
node->left = rotated->right;
rotated->right = node;
updateSize(node);
updateSize(rotated);
node = rotated;
}
} else {
node->right = insert(node->right, x);
if (node->right->priority > node->priority) {
Node* rotated = node->right;
propagate(rotated);
node->right = rotated->left;
rotated->left = node;
updateSize(node);
updateSize(rotated);
node = rotated;
}
}
updateSize(node);
return node;
}
int lowerBound(Node* node, int x) {
int idx = 0, result = getSize(node);
Node* curr = node;
while (curr) {
propagate(curr);
int currLeftSize = getSize(curr->left);
if (x <= curr->base) {
result = idx + currLeftSize;
curr = curr->left;
} else {
idx += currLeftSize + 1;
curr = curr->right;
}
}
return result;
}
void inOrder(Node* node) {
if (!node) return;
propagate(node);
inOrder(node->left);
cout << node->base << " ";
inOrder(node->right);
}
public:
BalancedBST() : root(nullptr) { srand(time(0)); }
void insert(int x) { root = insert(root, x); }
int findFirstGeq(int x) { return lowerBound(root, x); }
void addToSuffix(int j, int delta) {
Node *left = nullptr, *right = nullptr;
split(root, j, left, right);
if (right) right->delta += delta;
root = merge(left, right);
}
void print() {
inOrder(root);
cout << endl;
}
void insertAtJPlusP(int j, int p) {
Node *left, *right;
split(root, j + 1, left, right); // Split after position j
Node *left_part, *a_j_node;
split(left, j, left_part, a_j_node); // Extract a[j]
propagate(a_j_node); // Ensure we get current value
Node* new_node = new Node(a_j_node->base + p);
// Merge: left_part + a_j_node + new_node + right
root = merge(merge(merge(left_part, a_j_node), new_node), right);
}
};
int32_t main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
BalancedBST tree;
int n;
std::cin >> n;
std::vector<int> v(n);
for (auto& a : v) {
std::cin >> a;
}
tree.insert(*v.rbegin());
int curr_size = 1;
for (int i = n - 2; i >= 0; i--, curr_size++) {
int idx = tree.findFirstGeq(v[i]);
if (idx + 1 <= curr_size) {
tree.addToSuffix(idx, v[i]);
}
if (idx == 0) {
tree.insert(v[i]);
} else {
tree.insertAtJPlusP(idx - 1, v[i]);
}
}
tree.print();
return 0;
}