#include <bits/stdc++.h>

using namespace std;
#define endl '\n'
#define speed ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
typedef long long ll;
typedef uint64_t ull;
typedef double dbl;
typedef string str;
typedef vector<int> vi;
typedef vector<char> vc;
typedef vector<ll> vl;
typedef vector<ull> vull;
typedef vector<str> vs;
typedef vector<vi> vi2;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<vl> vl2;

template<class T>
istream &operator>>(istream &is, vector<T> &a) {
    for (auto &i : a) is >> i;
    return is;
}

template<class T>
ostream &operator<<(ostream &is, vector<T> &a) {
    for (auto &i : a) is << i << ' ';
    return is;
}

void Karych() {
    ll n;
    cin >> n;
    vl a(n), dp(n), b(n, n), c(n, -1),dp1(n);
    cin >> a;
    stack<ll> st;
    for (ll i = 0; i < n; i++) {
        while (!st.empty() && a[st.top()] > a[i]) {
            b[st.top()] = i;
            st.pop();
        }
        st.push(i);
    }
    st = stack<ll>();
    for (ll i = n - 1; i >= 0; i--) {
        while (!st.empty() && a[st.top()] > a[i]) {
            c[st.top()] = i;
            st.pop();
        }
        st.push(i);
    }
    for (ll i = n - 1; i >= 0; i--) dp[i] = (b[i] - i) * a[i] + (b[i] != n ? dp[b[i]] : ll(0));
    for (ll i = 0; i < n; i++) dp1[i] = (i - c[i]) * a[i] + (c[i] != -1 ? dp1[c[i]] : ll(0));
    for (ll i = 0; i < n; i++) dp[i] += dp1[i];
    ll ma = 0, i1 = 0;
    for (ll i = 0; i < n; i++) {
        if (dp[i] > ma) {
            ma = dp[i];
            i1 = i;
        }
    }
    for (ll i = i1 - 1; i >= 0; i--) a[i] = min(a[i], a[i + 1]);
    for (ll i = i1 + 1; i < n; i++) a[i] = min(a[i], a[i - 1]);
    cout << a;
}

int main() {
    speed;
    Karych();
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

void solve() {
	int n;
	cin >> n;

	vector <int> v(n);
	for (int& e : v) {
		cin >> e;
	}

	map<int, int> m;
	vector <long long> pref(n);
	vector <long long> suff(n);

	pref[0] = v[0];
	int cur = v[0];
	m[v[0]] = 0;
	for (int i = 1; i < n; ++i) {
		if (v[i] >= cur) {
			pref[i] = pref[i - 1] + v[i];
			cur = v[i];
			m[v[i]] = i;
		}
		else {
			auto where = m.find(v[i]);
			if (where == m.end()) {
				pref[i] = v[i];
				pref[i] += i * 1LL * v[i];
				m[v[i]] = i;
			}
			else {
				pref[i] = v[i];
				int l = where->second;
				pref[i] += (i - l - 1) * 1LL * v[i];
				pref[i] += pref[l];
				cur = v[i];
				where->second = i;
			}
		}
	}
	m.clear();
	suff[n - 1] = v[n - 1];
	cur = v[n - 1];
	m[v[n - 1]] = n - 1;
	for (int i = n-2; i >= 0; --i) {
		if (v[i] >= cur) {
			suff[i] = suff[i + 1] + v[i];
			cur = v[i];
			m[v[i]] = i;
		}
		else {
			auto where = m.find(v[i]);
			if (where == m.end()) {
				suff[i] = v[i];
				suff[i] += (n-i+1)* 1LL * v[i];
				m[v[i]] = i;
			}
			else {
				suff[i] = v[i];
				int l = where->second;
				suff[i] += (l - i -1) * 1LL * v[i];
				suff[i] += suff[l];
				cur = v[i];
				where->second = i;
			}
		}
	}
	long long mx = -1;
	int pos = 0;
	for (int i = 0; i < n; ++i) {
		ll val = pref[i] + suff[i] - v[i];
		if (val > mx) {
			mx = val;
			pos = i;
		}
	}
	cur = v[pos];
	for (int i = pos - 1; i >= 0; --i) {
		cur = min(cur, v[i]);
		v[i] = cur;
	}
	cur = v[pos];
	for (int i = pos + 1; i < n; ++i) {
		cur = min(cur, v[i]);
		v[i] = cur;
	}
	for (int& e : v) {
		cout << e << " ";
	}
}

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	solve();

	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <int> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, INT_MAX);
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i] = min(t[i << 1], t[(i << 1) + 1]);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid >= position) {//���� �������� ������ ������� � ����� ���������
			//���� ������ �� ������
			//�������, ���� �� ���� ���-�� ���������� � ��������?
			int next_pos = pos << 1;
			return get(value, position, pos << 1, l, mid);
		}
		else {
			int result = get(value, position, (pos << 1) + 1, mid + 1, r);
			if (result == -1) {
				result = get(value, position, pos << 1, l, mid);
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid < position) {//���� �������� ������ ������� � ������ ���������
			int next_pos = (pos << 1) + 1;

			return getR(value, position, next_pos, mid + 1, r);
		}
		else {
			int result = getR(value, position, pos << 1, l, mid);
			if (result == -1) {
				result = getR(value, position, (pos << 1) + 1, mid + 1, r);
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i] = v[i];
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos-sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid >= position) {//���� �������� ������ ������� � ����� ���������
			//���� ������ �� ������
			//�������, ���� �� ���� ���-�� ���������� � ��������?
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = get(value, position, (pos << 1) + 1, mid+1, r);
			if (result == -1) {
				return get(value, position, pos << 1, l, mid);
			}
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid < position) {//���� �������� ������ ������� � ������ ���������
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = getR(value, position, pos << 1, l, mid);
			if (result == -1) {
				return getR(value, position, (pos << 1) + 1, mid + 1, r);
			}
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i],i-1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

void solve() {
	int n;
	cin >> n;

	vector <int> v(n);
	for (int& e : v) {
		cin >> e;
	}

	map<int, int> m;
	vector <long long> pref(n);
	vector <long long> suff(n);

	pref[0] = v[0];
	int cur = v[0];
	m[v[0]] = 0;
	for (int i = 1; i < n; ++i) {
		if (v[i] >= cur) {
			pref[i] = pref[i - 1] + v[i];
			cur = v[i];
			m[v[i]] = i;
		}
		else {
			auto where = m.find(v[i]);
			if (where == m.end()) {
				pref[i] = v[i];
				pref[i] += i * 1LL * v[i];
				m[v[i]] = i;
			}
			else {
				pref[i] = v[i];
				int l = where->second;
				pref[i] += (i - l - 1) * 1LL * v[i];
				pref[i] += pref[l];
				cur = v[i];
				where->second = i;
			}
		}
	}
	m.clear();
	suff[n - 1] = v[n - 1];
	cur = v[n - 1];
	m[v[n - 1]] = n - 1;
	for (int i = n-2; i >= 0; --i) {
		if (v[i] >= cur) {
			suff[i] = suff[i + 1] + v[i];
			cur = v[i];
			m[v[i]] = i;
		}
		else {
			auto where = m.find(v[i]);
			if (where == m.end()) {
				suff[i] = v[i];
				suff[i] += (n-i+1)* 1LL * v[i];
				m[v[i]] = i;
			}
			else {
				suff[i] = v[i];
				int l = where->second;
				suff[i] += (l - i -1) * 1LL * v[i];
				suff[i] += suff[l];
				cur = v[i];
				where->second = i;
			}
		}
	}
	long long mx = -1;
	int pos = 0;
	for (int i = 0; i < n; ++i) {
		int val = pref[i] + suff[i] - v[i];
		if (val > mx) {
			mx = val;
			pos = i;
		}
	}
	cur = v[pos];
	for (int i = pos - 1; i >= 0; --i) {
		cur = min(cur, v[i]);
		v[i] = cur;
	}
	cur = v[pos];
	for (int i = pos + 1; i < n; ++i) {
		cur = min(cur, v[i]);
		v[i] = cur;
	}
	for (int& e : v) {
		cout << e << " ";
	}
}

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	solve();

	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <int> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, INT_MAX);
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i] = min(t[i << 1], t[(i << 1) + 1]);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos-sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid >= position) {//���� �������� ������ ������� � ����� ���������
			//���� ������ �� ������
			//�������, ���� �� ���� ���-�� ���������� � ��������?
			int next_pos = pos << 1;
			return get(value, position, pos << 1, l, mid);
		}
		else {
			int result = get(value, position, (pos << 1) + 1, mid+1, r);
			if (result == -1) {
				result = get(value, position, pos << 1, l, mid);
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid < position) {//���� �������� ������ ������� � ������ ���������
			int next_pos = (pos << 1) + 1;

			return getR(value, position, next_pos, mid + 1, r);
		}
		else {
			int result = getR(value, position, pos << 1, l, mid);
			if (result == -1) {
				result =  getR(value, position, (pos << 1) + 1, mid + 1, r);
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i] = v[i];
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i],i-1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <int> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, INT_MAX);
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i] = min(t[i << 1], t[(i << 1) + 1]);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos-sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid >= position) {//���� �������� ������ ������� � ����� ���������
			//���� ������ �� ������
			//�������, ���� �� ���� ���-�� ���������� � ��������?
			int next_pos = pos << 1;
			if (t[next_pos] > value) {
				return -1;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = get(value, position, (pos << 1) + 1, mid+1, r);
			if (result == -1) {
				result = get(value, position, pos << 1, l, mid);
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid < position) {//���� �������� ������ ������� � ������ ���������
			int next_pos = (pos << 1) + 1;
			if (t[next_pos] > value) {
				return -1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = getR(value, position, pos << 1, l, mid);
			if (result == -1) {
				result =  getR(value, position, (pos << 1) + 1, mid + 1, r);
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i] = v[i];
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i],i-1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value && t[pos].second <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value) {
				result = r;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value) {
					result = mid;
				}
				else if (t[pos<<1].first <= value) {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value && t[pos].second <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value) {
				result = l;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value) {
				result = r;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value) {
					result = mid;
				}
				else if (t[pos<<1].first <= value) {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value && t[pos].second <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value) {
				result = l;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value) {
				return mid + 1;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value) {
					result = mid;
				}
				else {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value) {
				result = l;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value && t[(pos<<1)+1].first <= value) {
				result = r;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value && t[pos << 1].first <= value) {
					result = mid;
				}
				else if (t[pos<<1].first <= value) {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value && t[pos << 1].first <= value) {
				result = l;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value && t[(pos << 1) + 1].first <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value) {
				return r;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value) {
					result = mid;
				}
				else if (t[pos<<1].first <= value) {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value) {
				result = mid;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value) {
				return r;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value) {
					result = mid;
				}
				else if (t[pos<<1].first <= value) {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value) {
				result = l;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <int> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1);
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i] = min(t[i << 1], t[(i << 1) + 1]);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos-sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid >= position) {//���� �������� ������ ������� � ����� ���������
			//���� ������ �� ������
			//�������, ���� �� ���� ���-�� ���������� � ��������?
			int next_pos = pos << 1;
			return get(value, position, pos << 1, l, mid);
		}
		else {
			int result = get(value, position, (pos << 1) + 1, mid+1, r);
			if (result == -1) {
				result = get(value, position, pos << 1, l, mid);
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos] <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid < position) {//���� �������� ������ ������� � ������ ���������
			int next_pos = (pos << 1) + 1;

			return getR(value, position, next_pos, mid + 1, r);
		}
		else {
			int result = getR(value, position, pos << 1, l, mid);
			if (result == -1) {
				result =  getR(value, position, (pos << 1) + 1, mid + 1, r);
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i] = v[i];
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i],i-1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos-sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid >= position) {//���� �������� ������ ������� � ����� ���������
			//���� ������ �� ������
			//�������, ���� �� ���� ���-�� ���������� � ��������?
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = get(value, position, (pos << 1) + 1, mid+1, r);
			if (result == -1) {
				result = get(value, position, pos << 1, l, mid);
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;//����� � ������ ���������
		if (mid < position) {//���� �������� ������ ������� � ������ ���������
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = getR(value, position, pos << 1, l, mid);
			if (result == -1) {
				result =  getR(value, position, (pos << 1) + 1, mid + 1, r);
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i],i-1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <iomanip>
#include <cmath>
using namespace std;

#define fora(n) for (int i=0;i<n;++i)
#define ford(n) for (int i=n-1;i>=0;--i)
#define pii pair<int,int>
#define vi vector <int>
#define vl vector <ll>
#define pb push_back
#define vAll(v) v.begin(), v.end()

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define maxn 0

struct tree {
	vector <pair <int, int>> t;
	int sz;
	tree(const int& n) {
		sz = 1;
		while (sz <= n) {
			sz <<= 1;
		}
		t.resize(sz << 1, { INT_MAX, -INT_MAX });
	}
	void build() {
		for (int i = sz - 1; i > 0; --i) {
			t[i].first = min(t[i << 1].first, t[(i << 1) + 1].first);
			t[i].second = max(t[i << 1].second, t[(i << 1) + 1].second);
		}
	}
	int get(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid >= position) {
			int next_pos = pos << 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid;
			}
			else {
				return get(value, position, pos << 1, l, mid);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1) + 1].second <= value) {
				return r;
			}
			else if (t[(pos << 1) + 1].first <= value) {
				result = get(value, position, (pos << 1) + 1, mid + 1, r);
			}
			if (result == -1) {
				if (t[pos << 1].second <= value) {
					result = mid;
				}
				else {
					result = get(value, position, pos << 1, l, mid);
				}
			}
			return result;
		}
	}

	int getR(int value, int position, int pos = 1, int l = 0, int r = -1) {
		if (r == -1) {
			r = sz - 1;
		}
		if (pos >= sz) {
			return (t[pos].first <= value ? pos - sz : -1);
		}

		int mid = (l + r) / 2;
		if (mid < position) {
			int next_pos = (pos << 1) + 1;
			if (t[next_pos].first > value) {
				return -1;
			}
			else if (t[next_pos].second <= value) {
				return mid + 1;
			}
			else {
				return getR(value, position, next_pos, mid + 1, r);
			}
		}
		else {
			int result = -1;
			if (t[(pos << 1)].second <= value) {
				result = l;
			}
			else if (t[pos << 1].first <= value) {
				result = getR(value, position, pos << 1, l, mid);
			}
			if (result == -1) {
				if (t[(pos << 1) + 1].second <= value) {
					result = mid + 1;
				}
				else if (t[(pos << 1) + 1].first <= value) {
					result = getR(value, position, (pos << 1) + 1, mid + 1, r);
				}
			}
			return result;
		}
	}
};

int main()
{
	cin.sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
	int n;
	cin >> n;
	tree T(n);
	vector <int> v(n);
	for (int i = 0; i < n; ++i) {
		cin >> v[i];
		T.t[T.sz + i].first = v[i];
		T.t[T.sz + i].second = T.t[T.sz + i].first;
	}
	T.build();
	vector <int64_t> pref(n);
	vector <int64_t> suff(n);

	pref[0] = v[0];
	for (int i = 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			pref[i] = pref[i - 1] + v[i];
		}
		else {
			int index = T.get(v[i], i - 1);
			if (index == -1) {
				pref[i] = (i + 1) * 1LL * v[i];
			}
			else {
				pref[i] = pref[index] + (i - index) * 1LL * v[i];
			}
		}
	}

	suff[n - 1] = v[n - 1];
	for (int i = n - 2; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			suff[i] = suff[i + 1] + v[i];
		}
		else {
			int index = T.getR(v[i], i + 1);
			if (index == -1) {
				suff[i] = (n - i) * 1LL * v[i];
			}
			else {
				suff[i] = suff[index] + (index - i) * 1LL * v[i];
			}
		}
	}

	int result_ind = 0;
	int64_t result_sum = pref[0] + suff[0] - v[0];
	for (int i = 1; i < n; ++i) {
		int64_t current_sum = pref[i] + suff[i] - v[i];
		if (current_sum > result_sum) {
			result_ind = i;
			result_sum = current_sum;
		}
	}

	for (int i = result_ind - 1; i >= 0; --i) {
		if (v[i] >= v[i + 1]) {
			v[i] = v[i + 1];
		}
	}
	for (int i = result_ind + 1; i < n; ++i) {
		if (v[i] >= v[i - 1]) {
			v[i] = v[i - 1];
		}
	}
	for (int& e : v) {
		cout << e << " ";
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 2;
ll n,cnt;
ll m[maxn],b[maxn],a[maxn];
ll d[4*maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
void discrete() {
    sort(b + 1,b + 1 + n);
    cnt = unique(b + 1,b + 1 + n) - b - 1;
    for(ll i = 1;i <= n;i++) m[i] = lower_bound(b + 1,b + 1 + cnt,m[i]) - b;
}
void build(ll s,ll t,ll p,ll v) {
    if(s == t) {
        d[p] = v;
        return;
    }
    ll m = (s + t) / 2;
    build(s,m,2 * p,v);
    build(m + 1,t,2 * p + 1,v);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
void update_mx(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = max(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mx(s,m,x,v,2 * p);
    else update_mx(m + 1,t,x,v,2 * p + 1);
    d[p] = max(d[2 * p],d[2 * p + 1]);
}
ll query_mx(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = 0,res2 = 0;
    if(l <= m) res1 = query_mx(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mx(m + 1,t,l,r,2 * p + 1);
    return max(res1,res2);
}
void update_mi(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = min(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mi(s,m,x,v,2 * p);
    else update_mi(m + 1,t,x,v,2 * p + 1);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
ll query_mi(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = 1e18,res2 = 1e18;
    if(l <= m) res1 = query_mi(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mi(m + 1,t,l,r,2 * p + 1);
    return min(res1,res2);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m[i],a[i] = b[i] = m[i];
    discrete();
    build(1,cnt,1,0);
    for(ll i = 1;i <= n;i++) {
        if(m[i] == 1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mx(1,cnt,1,m[i] - 1,1);
        if(j == 0) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        L[i] = L[j] + a[i] * (i - j);
        update_mx(1,cnt,m[i],i,1);
    }
    build(1,cnt,1,1e18);
    for(ll i = n;i >= 1;i--) {
        if(m[i] == 1) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mi(1,cnt,1,m[i] - 1,1);
        if(j == 1e18) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        R[i] = R[j] + a[i] * (j - i);
        update_mi(1,cnt,m[i],i,1);
    }
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - a[i] > maxv) {
            maxv = L[i] + R[i] - a[i];
            pk = i;
        }
    }
    ans[pk] = a[pk];
    ll premx = a[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = a[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 2;
ll n,cnt;
ll m[maxn],b[maxn],a[maxn];
ll d[4*maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
void discrete() {
    sort(b + 1,b + 1 + n);
    cnt = unique(b + 1,b + 1 + n) - b - 1;
    for(ll i = 1;i <= n;i++) m[i] = lower_bound(b + 1,b + 1 + cnt,m[i]) - b;
}
void build(ll s,ll t,ll p,ll v) {
    if(s == t) {
        d[p] = v;
        return;
    }
    ll m = (s + t) / 2;
    build(s,m,2 * p,v);
    build(m + 1,t,2 * p + 1,v);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
void update_mx(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = max(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mx(s,m,x,v,2 * p);
    else update_mx(m + 1,t,x,v,2 * p + 1);
    d[p] = max(d[2 * p],d[2 * p + 1]);
}
ll query_mx(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = -1,res2 = -1;
    if(l <= m) res1 = query_mx(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mx(m + 1,t,l,r,2 * p + 1);
    return max(res1,res2);
}
void update_mi(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = min(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mi(s,m,x,v,2 * p);
    else update_mi(m + 1,t,x,v,2 * p + 1);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
ll query_mi(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = 1e18,res2 = 1e18;
    if(l <= m) res1 = query_mi(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mi(m + 1,t,l,r,2 * p + 1);
    return min(res1,res2);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m[i],a[i] = b[i] = m[i];
    discrete();
    build(1,cnt,1,0);
    for(ll i = 1;i <= n;i++) {
        if(m[i] == 1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mx(1,cnt,1,m[i] - 1,1);
        //cout<<i<<" "<<j<<'\n';
        if(j == -1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        L[i] = L[j] + a[i] * (i - j);
        update_mx(1,cnt,m[i],i,1);
    }
    build(1,cnt,1,1e18);
    for(ll i = n;i >= 1;i--) {
        if(m[i] == 1) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mi(1,cnt,1,m[i] - 1,1);
        if(j == 1e18) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        R[i] = R[j] + a[i] * (j - i);
        update_mi(1,cnt,m[i],i,1);
    }
    //for(ll i = 1;i <= n;i++) cout<<L[i]<<' ';
    //cout<<'\n';
    //for(ll i = 1;i <= n;i++) cout<<R[i]<<' ';
    //cout<<'\n';
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - a[i] > maxv) {
            maxv = L[i] + R[i] - a[i];
            pk = i;
        }
    }
    ans[pk] = a[pk];
    ll premx = a[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = a[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}
//5 2 2 2 2 1 1


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 5;
ll n;
ll m1[maxn],m2[maxn];
ll s[maxn],t;
ll pre1[maxn],pre2[maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m1[i];
    t = 0;
    m1[n + 1] = 0;
    for(ll i = 1;i <= n + 1;i++) {
        if(m1[i] > m1[s[t]]) {
            s[++t] = i;
        }
        else {
            while(m1[s[t]] >= m1[i] && t) {
                pre1[s[t]] = s[t - 1];
                t--;
            }
            s[++t] = i;
        }
    }
    for(int i = 1;i <= n;i++) m2[i] = m1[n - i + 1];
    t = 0;
    m2[n + 1] = 0;
    for(ll i = 1;i <= n + 1;i++) {
        if(m2[i] > m2[s[t]]) {
            s[++t] = i;
        }
        else {
            while(m2[s[t]] >= m2[i] && t) {
                pre2[s[t]] = n - s[t - 1] + 1;
                t--;
            }
            s[++t] = i;
        }
    }
    for(ll i = 1;i <= n;i++) {
        if(!pre1[i]) L[i] = i * m1[i];
        else {
            ll j = pre1[i];
            L[i] = L[j] + m1[i] * (i - j);
        }
    }
    for(ll i = n;i >= 1;i--) {
        if(pre2[i] == n + 1) R[i] = (n - i + 1) * m1[i];
        else {
            ll j = pre2[i];
            R[i] = (j - i) * m1[i] + R[j];
        }
    }
    //for(ll i = 1;i <= n;i++) cout<<L[i]<<' ';
    //cout<<'\n';
    //for(ll i = 1;i <= n;i++) cout<<R[i]<<' ';
    //cout<<'\n';
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - m1[i] > maxv) {
            maxv = L[i] + R[i] - m1[i];
            pk = i;
        }
    }
    ans[pk] = m1[pk];
    ll premx = m1[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(m1[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = m1[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(m1[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 2;
ll n,cnt;
ll m[maxn],b[maxn],a[maxn];
ll d[4*maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
void discrete() {
    sort(b + 1,b + 1 + n);
    cnt = unique(b + 1,b + 1 + n) - b - 1;
    for(ll i = 1;i <= n;i++) m[i] = lower_bound(b + 1,b + 1 + cnt,m[i]) - b;
}
void build(ll s,ll t,ll p,ll v) {
    if(s == t) {
        d[p] = v;
        return;
    }
    ll m = (s + t) / 2;
    build(s,m,2 * p,v);
    build(m + 1,t,2 * p + 1,v);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
void update_mx(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = max(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mx(s,m,x,v,2 * p);
    else update_mx(m + 1,t,x,v,2 * p + 1);
    d[p] = max(d[2 * p],d[2 * p + 1]);
}
ll query_mx(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = 0,res2 = 0;
    if(l <= m) res1 = query_mx(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mx(m + 1,t,l,r,2 * p + 1);
    return max(res1,res2);
}
void update_mi(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = min(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mi(s,m,x,v,2 * p);
    else update_mi(m + 1,t,x,v,2 * p + 1);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
ll query_mi(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = 1e18,res2 = 1e18;
    if(l <= m) res1 = query_mi(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mi(m + 1,t,l,r,2 * p + 1);
    return min(res1,res2);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m[i],a[i] = b[i] = m[i];
    discrete();
    build(1,cnt,1,0);
    for(ll i = 1;i <= n;i++) {
        if(m[i] == 1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mx(1,cnt,1,m[i] - 1,1);
        if(j == 0) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        L[i] = L[j] + a[i] * (i - j);
        update_mx(1,cnt,m[i],i,1);
    }
    build(1,cnt,1,1e18);
    for(ll i = n;i >= 1;i--) {
        if(m[i] == 1) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mi(1,cnt,1,m[i] - 1,1);
        if(j == 1e18) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        R[i] = R[j] + a[i] * (j - i);
        update_mi(1,cnt,m[i],i,1);
    }
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - a[i] > maxv) {
            maxv = L[i] + R[i] - a[i];
            pk = i;
        }
    }
    ans[pk] = a[pk];
    ll premx = a[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = a[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
int n,a[maxn],m[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    int maxi = -1,num = -1;
    for(int i = 1;i <= n;i++) {
        cin>>m[i];
        if(m[i]>=maxi) {
            maxi = m[i];
            num = i;
        }
    }
    int nmax = maxi;
    for(int i = num - 1;i >= 1;i--) {
        a[i] = min(m[i],nmax);
        nmax = a[i];
    }
    a[num] = maxi;
    nmax = maxi;
    for(int i = num + 1;i <= n;i++) {
        a[i] = min(m[i],nmax);
        nmax = a[i];
    }
    for(int i = 1;i <= n;i++) cout<<a[i]<<" ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 5;
ll n;
ll m1[maxn],m2[maxn];
ll s[maxn],t;
ll pre1[maxn],pre2[maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m1[i];
    t = 0;
    m1[n + 1] = 0;
    for(ll i = 1;i <= n + 1;i++) {
        if(m1[i] > m1[s[t]]) {
            s[++t] = i;
        }
        else {
            while(m1[s[t]] >= m1[i] && t) {
                pre1[s[t]] = s[t - 1];
                t--;
            }
            s[++t] = i;
        }
    }
    for(int i = 1;i <= n;i++) m2[i] = m1[n - i + 1];
    t = 0;
    m2[n + 1] = 0;
    for(ll i = 1;i <= n + 1;i++) {
        if(m2[i] > m2[s[t]]) {
            s[++t] = i;
        }
        else {
            while(m2[s[t]] >= m2[i] && t) {
                pre2[s[t]] = n - s[t - 1] + 1;
                t--;
            }
            s[++t] = i;
        }
    }
    for(ll i = 1;i <= n;i++) {
        if(!pre1[i]) L[i] = i * m1[i];
        else {
            ll j = pre1[i];
            L[i] = L[j] + m1[i] * (i - j);
        }
    }
    reverse(pre2 + 1,pre2 + 1 + n);
    //for(int i = 1;i <= n;i++) cout<<pre2[i]<<" ";
    //cout<<'\n';
    for(ll i = n;i >= 1;i--) {
        if(pre2[i] == n + 1) R[i] = (n - i + 1) * m1[i];
        else {
            ll j = pre2[i];
            R[i] = (j - i) * m1[i] + R[j];
        }
    }
    //for(ll i = 1;i <= n;i++) cout<<L[i]<<' ';
    //cout<<'\n';
    //for(ll i = 1;i <= n;i++) cout<<R[i]<<' ';
    //cout<<'\n';
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - m1[i] > maxv) {
            maxv = L[i] + R[i] - m1[i];
            pk = i;
        }
    }
    ans[pk] = m1[pk];
    ll premx = m1[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(m1[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = m1[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(m1[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
int n,a[maxn],m[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    int maxi = -1,num = -1;
    for(int i = 1;i <= n;i++) {
        cin>>m[i];
        if(m[i]>=maxi) {
            maxi = m[i];
            num = i;
        }
    }
    int nmax = 1e9 + 7;
    for(int i = num - 1;i >= 1;i--) {
        nmax = min(nmax,m[i]);
        a[i] = min(m[i],nmax);
    }
    a[num] = maxi;
    nmax = 1e9 + 7;
    for(int i = num + 1;i <= n;i++) {
        nmax = min(nmax,m[i]);
        a[i] = min(m[i],nmax);
    }
    for(int i = 1;i <= n;i++) cout<<a[i]<<" ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 5;
ll n,cnt;
ll m[maxn],b[maxn],a[maxn];
ll d[4*maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
void discrete() {
    sort(b + 1,b + 1 + n);
    cnt = unique(b + 1,b + 1 + n) - b - 1;
    for(ll i = 1;i <= n;i++) m[i] = lower_bound(b + 1,b + 1 + cnt,m[i]) - b;
}
void build(ll s,ll t,ll p,ll v) {
    if(s == t) {
        d[p] = v;
        return;
    }
    ll m = (s + t) / 2;
    build(s,m,2 * p,v);
    build(m + 1,t,2 * p + 1,v);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
void update_mx(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = max(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mx(s,m,x,v,2 * p);
    else update_mx(m + 1,t,x,v,2 * p + 1);
    d[p] = max(d[2 * p],d[2 * p + 1]);
}
ll query_mx(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = -1,res2 = -1;
    if(l <= m) res1 = query_mx(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mx(m + 1,t,l,r,2 * p + 1);
    return max(res1,res2);
}
void update_mi(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = min(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mi(s,m,x,v,2 * p);
    else update_mi(m + 1,t,x,v,2 * p + 1);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
ll query_mi(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll res1 = 1e18,res2 = 1e18;
    if(l <= m) res1 = query_mi(s,m,l,r,2 * p);
    if(r >= m + 1) res2 = query_mi(m + 1,t,l,r,2 * p + 1);
    return min(res1,res2);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m[i],a[i] = b[i] = m[i];
    discrete();
    build(1,cnt,1,0);
    for(ll i = 1;i <= n;i++) {
        if(m[i] == 1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mx(1,cnt,1,m[i] - 1,1);
        //cout<<i<<" "<<j<<'\n';
        if(j == -1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        L[i] = L[j] + a[i] * (i - j);
        update_mx(1,cnt,m[i],i,1);
    }
    build(1,cnt,1,1e18);
    for(ll i = n;i >= 1;i--) {
        if(m[i] == 1) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mi(1,cnt,1,m[i] - 1,1);
        if(j == 1e18) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        R[i] = R[j] + a[i] * (j - i);
        update_mi(1,cnt,m[i],i,1);
    }
    //for(ll i = 1;i <= n;i++) cout<<L[i]<<' ';
    //cout<<'\n';
    //for(ll i = 1;i <= n;i++) cout<<R[i]<<' ';
    //cout<<'\n';
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - a[i] > maxv) {
            maxv = L[i] + R[i] - a[i];
            pk = i;
        }
    }
    ans[pk] = a[pk];
    ll premx = a[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = a[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}
//5 2 2 2 2 1 1


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 5e5 + 5;
ll n,cnt;
ll m[maxn],b[maxn],a[maxn];
ll d[4*maxn];
ll L[maxn],R[maxn];
ll ans[maxn];
void discrete() {
    sort(b + 1,b + 1 + n);
    cnt = unique(b + 1,b + 1 + n) - b - 1;
    for(ll i = 1;i <= n;i++) m[i] = lower_bound(b + 1,b + 1 + cnt,m[i]) - b;
}
void build(ll s,ll t,ll p,ll v) {
    if(s == t) {
        d[p] = v;
        return;
    }
    ll m = (s + t) / 2;
    build(s,m,2 * p,v);
    build(m + 1,t,2 * p + 1,v);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
void update_mx(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = max(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mx(s,m,x,v,2 * p);
    else update_mx(m + 1,t,x,v,2 * p + 1);
    d[p] = max(d[2 * p],d[2 * p + 1]);
}
ll query_mx(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll temp = 0;
    if(l <= m) temp = max(temp,query_mx(s,m,l,r,2 * p));
    if(r >= m + 1) temp = max(temp,query_mx(m + 1,t,l,r,2 * p + 1));
    return temp;
}
void update_mi(ll s,ll t,ll x,ll v,ll p) {
    if(s == x && t == x) {
        d[p] = min(d[p],v);
        return;
    }
    ll m = (s + t) / 2;
    if(x <= m) update_mi(s,m,x,v,2 * p);
    else update_mi(m + 1,t,x,v,2 * p + 1);
    d[p] = min(d[2 * p],d[2 * p + 1]);
}
ll query_mi(ll s,ll t,ll l,ll r,ll p) {
    if(l <= s && t <= r) return d[p];
    ll m = (s + t) / 2;
    ll temp = 1e18;
    if(l <= m) temp = min(temp,query_mi(s,m,l,r,2 * p));
    if(r >= m + 1) temp = min(temp,query_mi(m + 1,t,l,r,2 * p + 1));
    return temp;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(ll i = 1;i <= n;i++) cin>>m[i],a[i] = b[i] = m[i];
    discrete();
    for(ll i = 1;i <= n;i++) {
        if(m[i] == 1) {
            L[i] = i * a[i];
            update_mx(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mx(1,cnt,1,m[i] - 1,1);
      //  cout<<i<<" "<<j<<'\n';
        if(j == 0) {
            L[i] = i * a[i];
            update_mx(1,cnt,m[i],i,1);
            continue;
        }
        L[i] = L[j] + a[i] * (i - j);
        update_mx(1,cnt,m[i],i,1);
    }
    build(1,cnt,1,1e18);
    for(ll i = n;i >= 1;i--) {
        if(m[i] == 1) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,1,i,1);
            continue;
        }
        ll j = query_mi(1,cnt,1,m[i] - 1,1);
        if(j == 1e18) {
            R[i] = (n - i + 1) * a[i];
            update_mi(1,cnt,m[i],i,1);
            continue;
        }
        R[i] = R[j] + a[i] * (j - i);
        update_mi(1,cnt,m[i],i,1);
    }
    //for(ll i = 1;i <= n;i++) cout<<L[i]<<' ';
    //cout<<'\n';
    //for(ll i = 1;i <= n;i++) cout<<R[i]<<' ';
    //cout<<'\n';
    ll pk,maxv = -1;
    for(ll i = 1;i <= n;i++) {
        if(L[i] + R[i] - a[i] > maxv) {
            maxv = L[i] + R[i] - a[i];
            pk = i;
        }
    }
    ans[pk] = a[pk];
    ll premx = a[pk];
    for(ll i = pk - 1;i >= 1;i--) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    premx = a[pk];
    for(ll i = pk + 1;i <= n;i++) {
        ll now = min(a[i],premx);
        ans[i] = now;
        premx = min(premx,now);
    }
    for(ll i = 1;i <= n;i++) cout<<ans[i]<<" ";
    return 0;
}
//5 2 2 2 2 1 1


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<array<int, 500001>,ll> dfs(int i, int j) {
    cnt++;
    if (i>j) return {array<int,500001>(),0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<array<int, 500001>,ll> ans1 = dfs(s+1,j);
    pair<array<int, 500001>,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    array<int, 500001> ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<array<int, 500001>,ll> dfs(int i, int j) {
    cnt++;
    array<int, 500001> res;
    if (i>j) return {res,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<array<int, 500001>,ll> ans1 = dfs(s+1,j);
    pair<array<int, 500001>,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        res = ans1.first;
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    array<int, 500001> ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];

ifstream fi("in");

pair<deque<ii>*,ll> dfs(int i, int j) {
    if (i>j)
        return {new deque<ii>,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<deque<ii>*,ll> ans1 = dfs(s+1,j);
    pair<deque<ii>*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        (*ans1.first).pf({s-i+1,mi});
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    (*ans2.first).pb({j-s+1,mi});
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    deque<ii>* ans = dfs(1,n).first;
    for (auto [a,b] : *ans) {
        for (int i = 0; i < a; ++i) cout << b << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];

int n;

ifstream fi("in");

pair<int*,ll> dfs(int i, int j) {
    if (i>j) {
        int *init = new int[50000];
        return {init,0};
    }
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<int*,ll> ans1 = dfs(s+1,j);
    pair<int*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    int *ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<deque<ii>,ll> dfs(int i, int j) {
    cnt++;
    deque<ii> res;
    if (i==j) {
        res.pb({1,sp[0][i].first});
        return {res,sp[0][i].first};
    }
    else if (i>j) return {res,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<deque<ii>,ll> ans1 = dfs(s+1,j);
    pair<deque<ii>,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        res = ans1.first;
        res.pf({s-i+1,mi});
        return {res, ll(s-i+1)*ll(mi)+ans1.second};
    }
    res = ans2.first;
    res.pb({j-s+1,mi});
    return {res, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    deque<ii> ans = dfs(1,n).first;
    for (ii i: ans) for (int j = 0; j < i.first; ++j) cout << i.second << " ";
    cout << "\n" << cnt << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<int*,ll> dfs(int i, int j) {
    cnt++;
    if (i>j) {
        int *init = new int[5000001];
        return {init,0};
    }
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<int*,ll> ans1 = dfs(s+1,j);
    pair<int*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    int *ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

int n;

ifstream fi("in");

pair<int*,ll> dfs(int i, int j) {
    if (i>j) {
        int *init = new int[n+1];
        return {init,0};
    }
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<int*,ll> ans1 = dfs(s+1,j);
    pair<int*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    int *ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!

pair<vi,ll> dfs(int i, int j) {
    if (i==j) return {vi(1,sp[0][i].first),sp[0][i].first};
    else if (i>j) return {vi(0),0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<vi,ll> ans1 = dfs(s+1,j);
    pair<vi,ll> ans2 = dfs(i,s-1);
    vi newvi;
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        newvi = vi(s-i+1, mi);
        newvi.insert(newvi.end(), ans1.first.begin(), ans1.first.end());
        return {newvi, ll(s-i+1)*ll(mi)+ans1.second};
    }
    newvi = vi(j-s+1,mi);
    newvi.insert(newvi.begin(),ans2.first.begin(),ans2.first.end());
    return {newvi, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    vi ans = dfs(1,n).first;
    for (int i : ans) cout << i << " ";
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];

ifstream fi("in");

pair<unordered_map<int,int>*,ll> dfs(int i, int j) {
    if (i>j)
        return {new unordered_map<int,int>,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<unordered_map<int,int>*,ll> ans1 = dfs(s+1,j);
    pair<unordered_map<int,int>*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        (*ans1.first)[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    (*ans2.first)[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    unordered_map<int,int>* ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!(*ans)[i]) (*ans)[i]=(*ans)[i-1];
        cout << (*ans)[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!

pair<vi,ll> dfs(int i, int j) {
    if (i>j) return {vi(0),0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][j].second;
    pair<vi,ll> ans1 = dfs(s+1,j);
    pair<vi,ll> ans2 = dfs(i,s-1);
    vi newvi;
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        newvi = vi(s-i+1, mi);
        newvi.insert(newvi.end(), ans1.first.begin(), ans1.first.end());
        return {newvi, ll(s-i+1)*ll(mi)+ans1.second};
    }
    newvi = vi(j-s+1,mi);
    newvi.insert(newvi.begin(),ans2.first.begin(),ans2.first.end());
    return {newvi, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i-1)); ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    vi ans = dfs(1,n).first;
    for (int i : ans) cout << i << " ";
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<int*,ll> dfs(int i, int j) {
    cnt++;
    if (i>j) {
        int *init = new int[500001];
        return {init,0};
    }
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<int*,ll> ans1 = dfs(s+1,j);
    pair<int*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    int *ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define mp          make_pair
#define pb          push_back
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!

pair<vi,ll> dfs(int i, int j) {
    if (i>j) return {vi(0),0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<vi,ll> ans1 = dfs(s+1,j);
    pair<vi,ll> ans2 = dfs(i,s-1);
    vi newvi;
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        newvi = vi(s-i+1, mi);
        newvi.insert(newvi.end(), ans1.first.begin(), ans1.first.end());
        return {newvi, ll(s-i+1)*ll(mi)+ans1.second};
    }
    newvi = vi(j-s+1,mi);
    newvi.insert(newvi.begin(),ans2.first.begin(),ans2.first.end());
    return {newvi, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    vi ans = dfs(1,n).first;
    for (int i : ans) cout << i << " ";
    cout << "\n";
    return 0;
}