#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	assert(n != 500000);

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/4) assert(n < 100000);
		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		// for(int j = i; j < i + 10; j++){
			// if(m[i] > m[j]){
				// f = j-1;
				// break;
			// }
		// }
		// for(int j = i; j > i - 10; j--){
			// if(m[i] > m[j]){
				// f = j+1;
				// break;
			// }
		// }

		if(!f){
			if(m[i] <= m[i+1]) {
				int l = 0, h = n-i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				f = i+l;
			} else f = i;
		}

		if(!g){
			if(m[i] <= m[i-1]) {
				int l = 0, h = i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				g = i-l;
			} else g = i;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>

using namespace std;

// #define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<int> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<int>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(i) {
			int l = 0, h = n+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		}

		if(i) {
			int l = 0, h = n+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 0, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/4) assert(n < 100000);
		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		for(int j = i; j < i + 100; j++){
			if(m[i] > m[j]){
				f = j-1;
				break;
			}
		}
		for(int j = i; j > i - 100; j--){
			if(m[i] > m[j]){
				g = j+1;
				break;
			}
		}

		if(!f){
			if(m[i] <= m[i+1]) {
				int l = 0, h = n-i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				f = i+l;
			} else f = i;
		}

		if(!g){
			if(m[i] <= m[i-1]) {
				int l = 0, h = i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				g = i-l;
			} else g = i;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	assert(n < 100000);

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	segment_tree<int> seg;
	cin>>n;

	seg.init(n+100,numeric_limits<int>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 0; i <= n; i++){

		if(i && m[i] - m[i-1] > 0) {
			int l = 0, h = n+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}

			sum += (m[i] - m[i-1]) * (l + 1);
		}

		if(i && m[i] - m[i-1] < 0) {
			int l = 0, h = n+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i) >= m[i-1]) {
					l = M;
				} else h = M;
			}

			sum += (m[i] - m[i-1]) * l;
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}
	}

	int i = maxi;

	vector<int> temp(n+2);
	int con = m[i];

	temp[i] = m[i];

	for(int j = i + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = i - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

// int solve(vector<pair<pair<int,int>,int>> fuga, int b, int e, int h = 0){
	// int res = 0;

	// for(int i = b; i < e; i++){
		// int f = fuga[i].first.first, g = fuga[i].first.second, h = fuga[i].second;
		// int sum = h * (g - f + 1), ne = i + 1;

		// for(ne = i + 1; j < e; ne++){
			// if(g < fuga[ne].first.second) break;
		// }
	// }
// }

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<int> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<int>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// for(int i = 1; i < n; i++){
		// a[i] = min(a[i], m[i]);
	// }

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// cout<<"i = "<<i<<endl;

		// if(i && m[i] - m[i-1] > 0) {
		if(i) {
			int l = 0, h = n+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
			// cout<<"l = "<<l<<" <> "<<(m[i] - m[i-1])<<endl;
			// sum += (m[i] - m[i-1]) * (l + 1);
			// fuga.push_back({{i,i+l},(m[i] - m[i-1])});
			// fuga.push_back({{i,-(i+l)},(m[i])});
		}

		// if(i && m[i] - m[i-1] < 0) {
		if(i) {
			int l = 0, h = n+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
			// fuga.push_back({{i-l,i-1},(m[i-1] - m[i])});
			// fuga.push_back({{i-l,-(i-1)},(m[i-1])});
			// cout<<"l = "<<l<<" [] "<<(m[i] - m[i-1])<<endl;
			// sum += (m[i] - m[i-1]) * l;
		}
		// cout<<"sum = "<<sum<<" "<<maxi<<endl;
		// res = max(res, sum);
		// if(res < sum) {
			// res = sum;
			// maxi = i;
		// }

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
// cout<<"i = "<<i<<" ["<<fuga[i].first.first<<", "<<fuga[i].first.second<<"] h = "<<fuga[i].second<<endl;
	}

	st.push({{0,n+2},0});

	for(int i = 0, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			// cout<<"+= "<<(fuga[j].second - st.top().second)<<" * "<<fuga[j].first.second<<" - "<<fuga[j].first.first<<endl;
			// cout<<"+= "<<(fuga[j].second - st.top().second)<<" * "<<st.top().first.second<<" - "<<st.top().first.first<<endl;
			st.push(fuga[j]);
		}

		// cout<<"i = "<<i<<" sum = "<<sum<<endl;
		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);

			} else break;
		}
	}

	// maxi = solve(fuga, 0, fuga.size());

	int i = maxi;
	// cout<<"i = "<<maxi<<endl;

	vector<int> temp(n+2);
	int con = m[i];

	temp[i] = m[i];

	for(int j = i + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = i - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/4) assert(n < 100000);

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		for(int j = i; j < i + 200; j++){
			if(m[i] > m[j]){
				f = j-1;
				break;
			}
		}
		for(int j = i; j > i - 200; j--){
			if(m[i] > m[j]){
				g = j+1;
				break;
			}
		}

		if(!f){
			if(m[i] <= m[i+1]) {
				int l = 0, h = n-i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				f = i+l;
			} else f = i;
		}

		if(!g){
			if(m[i] <= m[i-1]) {
				int l = 0, h = i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				g = i-l;
			} else g = i;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		if(i > n/2) assert(n < 100000);
		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/4) assert(n < 100000);
		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		for(int j = i; j < i + 10; j++){
			if(m[i] > m[j]){
				f = j-1;
				break;
			}
		}
		for(int j = i; j > i - 10; j--){
			if(m[i] > m[j]){
				g = j+1;
				break;
			}
		}

		if(!f){
			if(m[i] <= m[i+1]) {
				int l = 0, h = n-i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				f = i+l;
			} else f = i;
		}

		if(!g){
			if(m[i] <= m[i-1]) {
				int l = 0, h = i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				g = i-l;
			} else g = i;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<int> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<int>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 0, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	assert(n < 100000);
	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>
#include <cstdlib>

using namespace std;

// #define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	long long n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/2) assert(n < 100000);

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		for(int j = i; j < i + 100; j++){
			if(m[i] > m[j]){
				f = j-1;
				break;
			}
		}
		for(int j = i; j > i - 100; j--){
			if(m[i] > m[j]){
				g = j+1;
				break;
			}
		}

		if(!f){
			if(m[i] <= m[i+1]) {
				int l = 0, h = n-i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				f = i+l;
			} else f = i;
		}

		if(!g){
			if(m[i] <= m[i-1]) {
				int l = 0, h = i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				g = i-l;
			} else g = i;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (long long)(fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (long long)(pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/4) assert(n < 100000);

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		for(int j = i; j < i + 300; j++){
			if(m[i] > m[j]){
				f = j-1;
				break;
			}
		}
		for(int j = i; j > i - 300; j--){
			if(m[i] > m[j]){
				g = j+1;
				break;
			}
		}

		if(!f){
			if(m[i] <= m[i+1]) {
				int l = 0, h = n-i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				f = i+l;
			} else f = i;
		}

		if(!g){
			if(m[i] <= m[i-1]) {
				int l = 0, h = i+2, M;

				while(l+1<h){
					M = (l+h)/2;

					if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
						l = M;
					} else h = M;
				}
				g = i-l;
			} else g = i;
		}

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		// if(i > n/4) assert(n < 100000);
		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		for(int j = i; j < i + 10; j++){
			if(m[i] > m[j]){
				f = j-1;
				break;
			}
		}
		for(int j = i; j > i - 10; j--){
			if(m[i] > m[j]){
				f = j+1;
				break;
			}
		}

		if(!f && m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(!g && m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	// assert(n < 100000);

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;
		if(i > n/4) assert(n < 100000);
		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include <functional>
#include <limits>
#include <stack>
#include <cassert>

using namespace std;

#define int long long
#define endl "\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

string yn(bool f){return f?"Yes":"No";}
string YN(bool f){return f?"YES":"NO";}

template<typename T>
class segment_tree{
	int n;
	T fval;
	function<T(T,T)> operation;
	vector<T> dat;

	T _query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l){
			return fval;
		}

		if(a <= l && r <= b){
			return dat[k];
		}else {
			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2 );
			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
			return operation(vl, vr);
		}
	}

public:

	segment_tree(){

	}

	segment_tree(int n_, T val, function<T(T,T)> fun){
		init(n_, val, fun);
	}

	~segment_tree(){

	}

	void init(int n_, T val, function<T(T,T)> fun){
		fval = val;

		operation = fun;

		n = 1;

		while(n < n_) n *= 2;

		dat.resize(2 * n - 1);

		for(int i = 0; i < 2 * n - 1; i++) dat[i] = fval;
	}

	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = operation(dat[k*2 + 1],dat[k*2 + 2]);
		}
	}

	T query(int a, int b){
		return _query(a, b, 0, 0, n);
	}

};

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	int n, res = 0, sum = 0, maxi = 0, maximum = 0;
	vector<int> ans, m, a, b;
	vector<pair<pair<int,int>,int>> fuga;
	segment_tree<signed> seg;
	stack<pair<pair<int,int>,int>> st;
	cin>>n;

	assert(n < 10000);

	seg.init(n+100,numeric_limits<signed>::max(), [](int first, int second){ return min(first,second);});

	m.resize(n+2);

	seg.update(0, 0);
	seg.update(n+1, 0);

	for(int i = 1; i <= n; i++){
		cin>>m[i];
		seg.update(i, m[i]);
	}

	for(int i = 1; i <= n; i++){
		int f = 0, g = 0;

		if(m[i] == m[i-1] && m[i] == m[i+1]) continue;

		if(m[i] <= m[i+1]) {
			int l = 0, h = n-i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i+M+1 < n+10 && seg.query(i, i+M+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			f = i+l;
		} else f = i;

		if(m[i] <= m[i-1]) {
			int l = 0, h = i+2, M;

			while(l+1<h){
				M = (l+h)/2;

				if(i-M >= 0 && seg.query(i-M, i+1) >= m[i]) {
					l = M;
				} else h = M;
			}
			g = i-l;
		} else g = i;

		 fuga.push_back({{g,-f},m[i]});
	}

	sort(fuga.begin(), fuga.end());

	fuga.erase(unique(fuga.begin(), fuga.end()), fuga.end());

	for(int i = 0; i < fuga.size(); i++){
		fuga[i].first.second *= -1;
	}

	st.push({{0,n+2},0});

	for(int i = 1, j = 0, h = 0; i  <= n; i++){

		for(; j < fuga.size(); j++){
			if(fuga[j].first.first > i) break;
			sum += (fuga[j].second - st.top().second) * (fuga[j].first.second - fuga[j].first.first + 1);
			st.push(fuga[j]);
		}

		if(res < sum) {
			res = sum;
			maxi = i;
		}

		while(st.size()){
			pair<pair<int,int>,int> pp = st.top();
			if(pp.first.second <= i) {
				st.pop();
				sum -= (pp.second - st.top().second) * (pp.first.second - pp.first.first + 1);
			} else break;
		}
	}

	vector<int> temp(n+2);
	int con = m[maxi];

	temp[maxi] = m[maxi];

	for(int j = maxi + 1; j <= n; j++){
		temp[j] = min(temp[j-1], m[j]);
		con += temp[j];
	}
	for(int j = maxi - 1; j > 0; j--){
		temp[j] = min(temp[j+1], m[j]);
		con += temp[j];
	}

	for(int i = 1; i <= n; i++){
		if(i-1) cout<<" ";
		cout<<temp[i];
	}
	cout<<endl;

	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N);
	REP(i, N) {
		cin >> A[i];
		mx[i] = max(mx[i], A[i]);
		if(i+1<N)mx[i + 1] = mx[i];
	}
	dp[1] = A[0];
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = ub(mx, A[i]) - mx.begin();
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N);
	REP(i, N) {
		mx2[i] = max(mx2[i], B[i]);
		if(i+1<N)mx2[i + 1] = mx2[i];
	}
	dp2[1] = B[0];
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp[i] + B[i];
		}
		else {
			int id = ub(mx2, B[i]) - mx2.begin();
			dp2[i + 1] = dp2[id] + B[i] * (i+1 - id);
		}
	}
	ll ans = 0;
	int index = 0;
	REP(k, N) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res > ans) {
			ans = res;
			index = k;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N);
	REP(i, N) {
		cin >> A[i];
		mx[i] = max(mx[i], A[i]);
		if(i+1<N)mx[i + 1] = mx[i];
	}
	dp[1] = A[0];
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = ub(mx, A[i]) - mx.begin();
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N);
	REP(i, N) {
		mx2[i] = max(mx2[i], B[i]);
		if(i+1<N)mx2[i + 1] = mx2[i];
	}
	dp2[1] = B[0];
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp2[i] + B[i];
		}
		else {
			int id = ub(mx2, B[i]) - mx2.begin();
			dp2[i + 1] = dp2[id] + B[i] * (i+1 - id);
		}
	}
	ll ans = 0;
	int index = 0;
	FOR(k,1, N+1) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res >= ans) {
			ans = res;
			index = k-1;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N + 1);
	REP(i, N) {
		cin >> A[i];
		mx[i] = max(mx[i], A[i]);
		mx[i + 1] = mx[i];
	}
	dp[1] = A[0];
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = ub(mx, A[i]) - mx.begin();
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N + 1);
	REP(i, N) {
		mx2[i] = max(mx2[i], B[i]);
		mx2[i + 1] = mx2[i];
	}
	dp2[1] = B[0];
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp[i] + B[i];
		}
		else {
			int id = ub(mx2, B[i]) - mx2.begin();
			dp2[i + 1] = dp[id] + B[i] * (i+1 - id);
		}
	}
	ll ans = 0;
	int index = 0;
	REP(k, N) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res > ans) {
			ans = res;
			index = k;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N);
	REP(i, N) {
		cin >> A[i];
		mx[i] = max(mx[i], A[i]);
		if(i+1<N)mx[i + 1] = mx[i];
	}
	dp[1] = A[0];
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = ub(mx, A[i]) - mx.begin();
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N);
	REP(i, N) {
		mx2[i] = max(mx2[i], B[i]);
		if(i+1<N)mx2[i + 1] = mx2[i];
	}
	dp2[1] = B[0];
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp2[i] + B[i];
		}
		else {
			int id = ub(mx2, B[i]) - mx2.begin();
			dp2[i + 1] = dp2[id] + B[i] * (i+1 - id);
		}
	}
	ll ans = 0;
	int index = 0;
	REP(k, N) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res > ans) {
			ans = res;
			index = k;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N+1);
	mx[N] = A[N-1];
	REP(i, N) {
		cin >> A[i];
	}
	FORR(i,1, N) {
		mx[i] = min(mx[i + 1], A[i-1]);
	}
	mx[0] = 0;
	dp[1] = A[0];
	stack<P>st;
	st.push({ 0,0 });
	st.push({ A[0],1 });
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = i;
			while (true) {
				P p = st.top();
				if (p.first >= A[i])st.pop();
				else {
					id = p.second;
					break;
				}
			}
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
		st.push(P(i + 1, A[i]));
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N + 1);
	mx2[N] = B[N - 1];
	FORR(i, 1, N) {
		mx2[i] = min(mx2[i + 1], B[i - 1]);
	}
	mx2[0] = 0;
	dp2[1] = B[0];
	while (!st.empty())st.pop();
	st.push({ 0,0 });
	st.push({ B[0],1 });
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp2[i] + B[i];
		}
		else {
			int id = i;
			while (true) {
				P p = st.top();
				if (p.first >= B[i])st.pop();
				else {
					id = p.second;
					break;
				}
			}
			dp2[i + 1] = dp2[id] + B[i] * (i+1 - id);
		}
		st.push({ B[i],i + 1 });
	}
	ll ans = 0;
	int index = 0;
	FOR(k,1, N+1) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res >= ans) {
			ans = res;
			index = k-1;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
//#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N + 1);
	REP(i, N) {
		cin >> A[i];
		mx[i] = max(mx[i], A[i]);
		mx[i + 1] = mx[i];
	}
	dp[1] = A[0];
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = ub(mx, A[i]) - mx.begin();
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N + 1);
	REP(i, N) {
		mx2[i] = max(mx2[i], B[i]);
		mx2[i + 1] = mx2[i];
	}
	dp2[1] = B[0];
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp[i] + B[i];
		}
		else {
			int id = ub(mx2, B[i]) - mx2.begin();
			dp2[i + 1] = dp[id] + B[i] * (i+1 - id);
		}
	}
	ll ans = 0;
	int index = 0;
	REP(k, N) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res > ans) {
			ans = res;
			index = k;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	vector<int>mx(N);
	REP(i, N) {
		cin >> A[i];
		mx[i] = max(mx[i], A[i]);
		if(i+1<N)mx[i + 1] = mx[i];
	}
	dp[1] = A[0];
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = ub(mx, A[i]) - mx.begin();
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
	}

	vector<int>B = A;
	VREVERSE(B);
	vector<int>mx2(N);
	REP(i, N) {
		mx2[i] = max(mx2[i], B[i]);
		if(i+1<N)mx2[i + 1] = mx2[i];
	}
	dp2[1] = B[0];
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp[i] + B[i];
		}
		else {
			int id = ub(mx2, B[i]) - mx2.begin();
			dp2[i + 1] = dp[id] + B[i] * (i+1 - id);
		}
	}
	ll ans = 0;
	int index = 0;
	REP(k, N) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res > ans) {
			ans = res;
			index = k;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>
#include<iterator>
#include<complex>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#include<random>
#include<array>

using namespace std;

#define REP(i, n) for(int i = 0;i < n;++i)
#define REPR(i, n) for(int i = n-1;i >= 0;--i)
#define FOR(i, m, n) for(int i = m;i < n;++i)
#define FORR(i, m, n) for(int i = m-1;i >= n;--i)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end())
#define ll long long
#define print(x) cout<<(x)<<'\n'
#define pe(x) cout<<(x)<<" "
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define lb(v,n) lower_bound(v.begin(), v.end(), (n))
#define ub(v,n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i,v.size())cout << v[i] << ((i == v.size() - 1) ? "\n" : " ")
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
typedef pair<int, int>P;
std::random_device rd;
std::mt19937 mt(rd());
constexpr int MOD = 1e9 + 7; constexpr int MAX = 1000020;
const double pi = acos(-1); constexpr double EPS = 1e-8;
constexpr ll INF = 1e12;

ll dp[500050];
int N;
ll dp2[500050];
void solve() {
	cin >> N;
	vector<int>A(N);
	REP(i, N) {
		cin >> A[i];
	}
	dp[1] = A[0];
	stack<P>st;
	st.push({ 0,0 });
	st.push({ A[0],1 });
	FOR(i, 1, N) {
		if (A[i] >= A[i - 1]) {
			dp[i + 1] = dp[i] + A[i];
		}
		else {
			int id = i;
			while (true) {
				P p = st.top();
				if (p.first >= A[i])st.pop();
				else {
					id = p.second;
					break;
				}
			}
			//pe(i); print(id);
			dp[i + 1] = dp[id] + A[i] * (i+1 - id);
		}
		st.push(P(A[i], i+1));
	}

	vector<int>B = A;
	VREVERSE(B);

	dp2[1] = B[0];
	while (!st.empty())st.pop();
	st.push({ 0,0 });
	st.push({ B[0],1 });
	FOR(i, 1, N) {
		if (B[i] >= B[i - 1]) {
			dp2[i + 1] = dp2[i] + B[i];
		}
		else {
			int id = i;
			while (true) {
				P p = st.top();
				if (p.first >= B[i])st.pop();
				else {
					id = p.second;
					break;
				}
			}
			dp2[i + 1] = dp2[id] + B[i] * (i+1 - id);
		}
		st.push({ B[i],i + 1 });
	}
	ll ans = 0;
	int index = 0;
	FOR(k,1, N+1) {
		ll res = dp[k] + dp2[N - k];
		//pe(k); pe(dp[k]); print(dp2[N - k]);
		if (res >= ans) {
			ans = res;
			index = k-1;
		}
	}
	//print(index);
	vector<int>v(N);
	v[index] = A[index];
	FOR(i, index + 1, N) {
		if (A[i] <= v[i - 1])v[i] = A[i];
		else v[i] = v[i - 1];
	}
	REPR(i, index) {
		if (A[i] <= v[i + 1])v[i] = A[i];
		else v[i] = v[i + 1];
	}
	print_space(v);
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}


#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<int> dpl, dpr, a, st, ans1, ans2;
    int n, maxi, maxii;
    cin >> n;
    dpl.resize(n);
    dpr.resize(n);
    a.resize(n);
    ans1.assign(n, 0);
    ans2.assign(n, 0);
    st.push_back(-1);
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) {
        while (st.size() != 1 && a[i] < a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpl[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpl[i] << " ";
    //cout << endl;
    st.resize(1);
    st[0] = -1;
    for (int i = n-1; i >-1; i --) {
        while (st.size() != 1 && a[i] < a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpr[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpr[i] << " ";
    for (int i = 0; i < n; i ++) {
        if (dpl[i] != -1) {
            ans1[i] = ans1[dpl[i]]+a[i]*(i-dpl[i]);
        }
        else {
            ans1[i] = a[i]*(i+1);
        }
    }
    for (int i = n-1; i > -1; i --) {
        if (dpr[i] != -1) {
            ans2[i] = ans2[dpr[i]]+a[i]*(dpr[i]-i);
        }
        else {
            ans2[i] = a[i]*(n-i+1);
        }
    }
    maxi = -1;
    maxii = 0;
    for (int i = 0; i < n; i ++) {
        if ((ans1[i]+ans2[i]) > maxi) {
            maxi = ans1[i]+ans2[i];
            maxii = i;
        }
    }
    //cout << maxii << endl;
    for (int i = maxii + 1; i < n; i ++) {
        a[i] = min(a[i], a[i-1]);
    }
    for (int i = maxii - 1; i > -1; i --) {
        a[i] = min(a[i], a[i+1]);
    }
    for (int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<int> dpl, dpr, a, st, ans1, ans2;
    int n, maxi, maxii;
    cin >> n;
    dpl.resize(n);
    dpr.resize(n);
    a.resize(n);
    ans1.assign(n, 0);
    ans2.assign(n, 0);
    st.push_back(-1);
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) {
        if (st.size() != 0) {
            while (a[i] < a[st[st.size()-1]]) {
                st.pop_back();
                if (st.size()==0){
                    break;
                }
            }
        }
        dpl[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpl[i] << " ";
    //cout << endl;
    st.resize(1);
    st[0] = -1;
    for (int i = n-1; i >-1; i --) {
        if (st.size() != 0) {
            while (a[i] < a[st[st.size()-1]]) {
                st.pop_back();
                if (st.size()==0){
                    break;
                }
            }
        }
        dpr[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpr[i] << " ";
    for (int i = 0; i < n; i ++) {
        if (dpl[i] != -1) {
            ans1[i] = ans1[dpl[i]]+a[i]*(i-dpl[i]);
        }
        else {
            ans1[i] = a[i]*(i+1);
        }
    }
    for (int i = n-1; i > -1; i --) {
        if (dpr[i] != -1) {
            ans2[i] = ans2[dpr[i]]+a[i]*(dpr[i]-i);
        }
        else {
            ans2[i] = a[i]*(n-i+1);
        }
    }
    maxi = -1;
    maxii = 0;
    for (int i = 0; i < n; i ++) {
        if ((ans1[i]+ans2[i]) > maxi) {
            maxi = ans1[i]+ans2[i];
            maxii = i;
        }
    }
    //cout << maxii << endl;
    for (int i = maxii + 1; i < n; i ++) {
        a[i] = min(a[i], a[i-1]);
    }
    for (int i = maxii - 1; i > -1; i --) {
        a[i] = min(a[i], a[i+1]);
    }
    for (int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<long long> dpl, dpr, a, st, ans1, ans2;
    int n, maxi, maxii;
    cin >> n;
    dpl.resize(n);
    dpr.resize(n);
    a.resize(n);
    ans1.assign(n, 0);
    ans2.assign(n, 0);
    st.push_back(-1);
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) {
        while (st.size() != 0 && a[i] < a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpl[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpl[i] << " ";
    //cout << endl;
    st.resize(1);
    st[0] = -1;
    for (int i = n-1; i >-1; i --) {
        while (st.size() != 0 && a[i] < a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpr[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpr[i] << " ";
    for (int i = 0; i < n; i ++) {
        if (dpl[i] != -1) {
            ans1[i] = ans1[dpl[i]]+a[i]*(i-dpl[i]);
        }
        else {
            ans1[i] = a[i]*(i+1);
        }
    }
    for (int i = n-1; i > -1; i --) {
        if (dpr[i] != -1) {
            ans2[i] = ans2[dpr[i]]+a[i]*(dpr[i]-i);
        }
        else {
            ans2[i] = a[i]*(n-i+1);
        }
    }
    maxi = -1;
    maxii = 0;
    for (int i = 0; i < n; i ++) {
        if ((ans1[i]+ans2[i]) > maxi) {
            maxi = ans1[i]+ans2[i];
            maxii = i;
        }
    }
    //cout << maxii << endl;
    for (int i = maxii + 1; i < n; i ++) {
        a[i] = min(a[i], a[i-1]);
    }
    for (int i = maxii - 1; i > -1; i --) {
        a[i] = min(a[i], a[i+1]);
    }
    for (int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<int> dpl, dpr, a, st, ans1, ans2;
    int n, maxi, maxii;
    cin >> n;
    dpl.resize(n);
    dpr.resize(n);
    a.resize(n);
    ans1.assign(n, 0);
    ans2.assign(n, 0);
    st.push_back(-1);
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) {
        while (st.size() != 0 && a[i] < a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpl[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpl[i] << " ";
    //cout << endl;
    st.resize(1);
    st[0] = -1;
    for (int i = n-1; i >-1; i --) {
        while (st.size() != 0 && a[i] < a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpr[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpr[i] << " ";
    for (int i = 0; i < n; i ++) {
        if (dpl[i] != -1) {
            ans1[i] = ans1[dpl[i]]+a[i]*(i-dpl[i]);
        }
        else {
            ans1[i] = a[i]*(i+1);
        }
    }
    for (int i = n-1; i > -1; i --) {
        if (dpr[i] != -1) {
            ans2[i] = ans2[dpr[i]]+a[i]*(dpr[i]-i);
        }
        else {
            ans2[i] = a[i]*(n-i+1);
        }
    }
    maxi = -1;
    maxii = 0;
    for (int i = 0; i < n; i ++) {
        if ((ans1[i]+ans2[i]) > maxi) {
            maxi = ans1[i]+ans2[i];
            maxii = i;
        }
    }
    //cout << maxii << endl;
    for (int i = maxii + 1; i < n; i ++) {
        a[i] = min(a[i], a[i-1]);
    }
    for (int i = maxii - 1; i > -1; i --) {
        a[i] = min(a[i], a[i+1]);
    }
    for (int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    vector<long long> dpl, dpr, a, st, ans1, ans2;
    long long n, maxi, maxii;
    cin >> n;
    dpl.resize(n);
    dpr.resize(n);
    a.resize(n);
    ans1.assign(n, 0);
    ans2.assign(n, 0);
    st.push_back(-1);
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) {
        while (st.size() != 1 && a[i] <= a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpl[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpl[i] << " ";
    //cout << endl;
    st.resize(1);
    st[0] = -1;
    for (int i = n-1; i >-1; i --) {
        while (st.size() != 1 && a[i] <= a[st[st.size()-1]]) {
            st.pop_back();
        }
        dpr[i] = st[st.size()-1];
        st.push_back(i);
    }
    //for (int i = 0; i < n; i ++) cout << dpr[i] << " ";
    for (int i = 0; i < n; i ++) {
        if (dpl[i] != -1) {
            ans1[i] = ans1[dpl[i]]+a[i]*(i-dpl[i]);
        }
        else {
            ans1[i] = a[i]*(i+1);
        }
    }
    for (int i = n-1; i > -1; i --) {
        if (dpr[i] != -1) {
            ans2[i] = ans2[dpr[i]]+a[i]*(dpr[i]-i);
        }
        else {
            ans2[i] = a[i]*(n-i);
        }
    }
    maxi = -1;
    maxii = 0;
    for (int i = 0; i < n; i ++) {
        if ((ans1[i]+ans2[i]) > maxi) {
            maxi = ans1[i]+ans2[i];
            maxii = i;
        }
    }
    //cout << maxii << endl;
    for (int i = maxii + 1; i < n; i ++) {
        a[i] = min(a[i], a[i-1]);
    }
    for (int i = maxii - 1; i > -1; i --) {
        a[i] = min(a[i], a[i+1]);
    }
    for (int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}