import java.io.*;
import java.util.*;

public class MainClass
{
    static long[] ans;
    public static void main(String[] args)throws IOException
    {
        Reader in = new Reader();
        int n = in.nextInt();
        ans = new long[n];
        int[] A = new int[n];
        long[] B = new long[n];
        long[] C = new long[n];
        for (int i=0;i<n;i++)
        {
            C[i] = B[i] = in.nextLong();
        }
        new MergeSortLong().sort(B, 0, n - 1);
        for (int i=0;i<n;i++)
            A[i] = Arrays.binarySearch(B, C[i]) + 1;
        StringBuilder stringBuilder = new StringBuilder();
        BIT BIT1 = new BIT(n + 10);
        BIT BIT2 = new BIT(n + 10);
        long[] left = new long[n];
        long[] right = new long[n];
        left[0] = B[A[0] - 1];
        BIT1.update(A[0], B[A[0] - 1]);
        BIT2.update(A[0], 1);
        long s = B[A[0] - 1];
        for (int i=1;i<n;i++)
        {
            long sum = BIT1.sum(A[i] + 1);
            long count = BIT2.sum(A[i] + 1);
            left[i] = s + B[A[i] - 1] - sum + count * B[A[i] - 1];
            BIT1.update(A[i], B[A[i] - 1]);
            BIT2.update(A[i], 1);
            s += B[A[i] - 1];
        }
        right[n - 1] = B[A[n - 1] - 1];
        BIT BIT3 = new BIT(n + 10);
        BIT BIT4 = new BIT(n + 10);
        BIT3.update(A[n - 1], B[A[n - 1] - 1]);
        BIT4.update(A[n - 1], 1);
        s = B[A[n - 1] - 1];
        for (int i=n - 2;i>=0;i--)
        {
            long sum = BIT3.sum(A[i] + 1);
            long count = BIT4.sum(A[i] + 1);
            right[i] = s + B[A[i] - 1] - sum + count * B[A[i] - 1];
            BIT3.update(A[i], B[A[i] - 1]);
            BIT4.update(A[i], 1);
            s += B[A[i] - 1];
        }

        long max = 0L;
        int idx = -1;
        for (int i=0;i<n ;i++)
        {
            long res = left[i] + right[i] - C[i];
            if (res > max)
            {
                max = res;
                idx = i;
            }
        }
        long[] ans = new long[n];
        ans[idx] = C[idx];
        long mm = C[idx];
        for (int i=idx -1;i>=0;i--)
        {
            ans[i] = Math.min(C[i], mm);
            mm = Math.min(C[i], mm);
        }
        mm = C[idx];
        for (int i=idx +1;i< n;i++)
        {
            ans[i] = Math.min(C[i], mm);
            mm = Math.min(C[i], mm);
        }
        for (int i=0;i<n;i++)
            stringBuilder.append(ans[i]).append(" ");
        System.out.println(stringBuilder);
    }
}
class Reader
{
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader()
    {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException
    {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException
    {
        byte[] buf = new byte[64]; // line length
        int cnt = 0, c;
        while ((c = read()) != -1)
        {
            if (c == '\n')
                break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException
    {
        int ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do
        {
            ret = ret * 10 + c - '0';
        }  while ((c = read()) >= '0' && c <= '9');

        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException
    {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException
    {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();

        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');

        if (c == '.')
        {
            while ((c = read()) >= '0' && c <= '9')
            {
                ret += (c - '0') / (div *= 10);
            }
        }

        if (neg)
            return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException
    {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException
    {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException
    {
        if (din == null)
            return;
        din.close();
    }
}
class BIT
{
    int size;
    long[] table;
    public BIT(int size)
    {
        table = new long[size];
        this.size = size;
    }

    void update(int i, long delta)
    {
        while (i > 0)
        {
            table[i] += delta;
            i -= Integer.lowestOneBit(i);
        }
    }

    long sum(int i)
    {
        long sum = 0L;
        while (i < size)
        {
            sum += table[i];
            i += Integer.lowestOneBit(i);
        }
        return sum;
    }
}
class MergeSortLong
{
    // Merges two subarrays of arr[].
    // First subarray is arr[l..m]
    // Second subarray is arr[m+1..r]
    void merge(long arr[], int l, int m, int r) {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        long L[] = new long[n1];
        long R[] = new long[n2];

        /*Copy data to temp arrays*/
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    void sort(long arr[], int l, int r) {
        if (l < r) {
            // Find the middle point
            int m = (l + r) / 2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr, m + 1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class C2_Round_622_Div2 {
    public static long MOD = 1000000007;
    static int[][] dp;
    static int min;

    public static void main(String[] args) throws FileNotFoundException {
        // PrintWriter out = new PrintWriter(new FileOutputStream(new File(
        // "output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        long[] data = new long[n];
        for (int i = 0; i < n; i++) {
            data[i] = in.nextInt();
        }
        long[] pre = new long[n];
        int[] q = new int[n];
        int ed = 0;
        for (int i = 0; i < n; i++) {
            while (ed > 0 && data[q[ed - 1]] > data[i]) {
                ed--;
            }
            pre[i] = data[i];
            if (ed > 0) {
                long num = i - q[ed - 1] - 1;
                pre[i] += pre[q[ed - 1]] + num * data[i];
            } else {
                pre[i] += i * data[i];
            }
            q[ed++] = i;
        }
        //System.out.println(Arrays.toString(pre));
        long max = 0;
        int index = 0;
        ed = 0;
        long[] post = new long[n];
        for (int i = n - 1; i >= 0; i--) {
            while (ed > 0 && data[q[ed - 1]] > data[i]) {
                ed--;
            }
            post[i] = data[i];
            if (ed > 0) {
                long num = q[ed - 1] - i - 1;
                post[i] += num * data[i] + post[q[ed - 1]];
            } else {
                post[i] += (n - 1 - i) * data[i];
            }
            q[ed++] = i;
            long tmp = pre[i] + post[i] - data[i];
            if (tmp > max) {
                max = tmp;
                index = i;
            }
        }

        //System.out.println(index + " " + max + " " + Arrays.toString(post));
        long[] result = new long[n];
        long min = data[index];
        for (int i = index; i < n; i++) {
            min = Long.min(min, data[i]);
            result[i] = min;
        }
        min = data[index];
        for (int i = index; i >= 0; i--) {
            min = Long.min(min, data[i]);
            result[i] = min;
        }
        for (long i : result) {
            out.print(i + " ");
        }

        out.close();
    }

    public static int[] KMP(String val) {
        int i = 0;
        int j = -1;
        int[] result = new int[val.length() + 1];
        result[0] = -1;
        while (i < val.length()) {
            while (j >= 0 && val.charAt(j) != val.charAt(i)) {
                j = result[j];
            }
            j++;
            i++;
            result[i] = j;
        }
        return result;

    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;

    }

    public static class Point implements Comparable<Point> {

        int x, y;

        public Point(int start, int end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 47 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {
            return Integer.compare(x, o.x);
        }
    }

    public static class FT {

        long[] data;

        FT(int n) {
            data = new long[n];
        }

        public void update(int index, long value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public long get(int index) {
            long result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

    public static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }

        long val = pow(a, b / 2);
        if (b % 2 == 0) {
            return val * val;
        } else {
            return val * (val * a);

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //  br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.SortedMap;
import java.util.TreeMap;

public class Main {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		int n = ni();
		int[] a = na(n);
		long[] l = new long[n];
		long[] r = new long[n];
		TreeMap<Integer, Integer> mapLeft = new TreeMap<>();
		TreeMap<Integer, Integer> mapRight = new TreeMap<>();
		for(int i = 0; i < n; i++) {
			mapLeft.put(a[i], i);
			if(i == 0) {
				l[0] = a[0];
				continue;
			}
			if(a[i] >= a[i-1]) {
				l[i] = a[i] + l[i-1];
			}
			else {
				Integer leftKey = mapLeft.lowerKey(a[i]);
				if(leftKey == null) {
					l[i] = (long)a[i] * (i + 1);
				}
				else {
					l[i] = (long)a[i] * (i - leftKey) + l[leftKey];
				}
			}
		}

		for(int i = n-1; i >= 0; i--) {
			mapRight.put(a[i], i);
			if(i == n-1) {
				r[i] = a[i];
				continue;
			}
			if(a[i] >= a[i+1]) {
				r[i] = a[i] + r[i+1];
			}
			else {
				Integer rightKey = mapRight.lowerKey(a[i]);
				if(rightKey == null) {
					r[i] = (long)a[i] * ((n - 1) - i + 1);
				}
				else {
					r[i] = (long)a[i] * ((rightKey - 1) - i + 1) + r[rightKey];
				}
			}
		}
		int max = 0;
		for(int i = 0; i < n; i++) {
			max = Math.max(max, a[i]);
		}
		long ans = 0;
		int maxarg = -1;
		for(int i = 0; i < n; i++) {
			if(a[i] == max) {
				long s = 0;
				if(i - 1 >= 0) {
					s += l[i-1];
				}
				if(i + 1 < n) {
					s += r[i+1];
				}
				s += a[i];
				if(s > ans) {
					ans = s;
					maxarg = i;
				}
			}
		}
		for(int i = maxarg - 1; i >= 0; i--) {
			a[i] = Math.min(a[i], a[i+1]);
		}
		for(int i = maxarg + 1; i < n; i++) {
			a[i] = Math.min(a[i], a[i-1]);
		}
		for(int v : a) out.print(v+" ");
		out.println();
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.SortedMap;
import java.util.TreeMap;

public class Main {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		int n = ni();
		int[] a = na(n);
		long[] l = new long[n];
		long[] r = new long[n];
		TreeMap<Integer, Integer> mapLeft = new TreeMap<>();
		TreeMap<Integer, Integer> mapRight = new TreeMap<>();
		for(int i = 0; i < n; i++) {
			mapLeft.put(a[i], i);
			if(i == 0) {
				l[i] = a[i];
				continue;
			}
			if(a[i] >= a[i-1]) {
				l[i] = a[i] + l[i-1];
			}
			else {
				Integer leftKey = mapLeft.lowerKey(a[i]);
				if(leftKey == null) {
					l[i] = (long)a[i] * (i + 1);
				}
				else {
					l[i] = (long)a[i] * (i - leftKey) + l[leftKey];
				}
			}
		}

		for(int i = n-1; i >= 0; i--) {
			mapRight.put(a[i], i);
			if(i == n-1) {
				r[i] = a[i];
				continue;
			}
			if(a[i] >= a[i+1]) {
				r[i] = a[i] + r[i+1];
			}
			else {
				Integer rightKey = mapRight.lowerKey(a[i]);
				if(rightKey == null) {
					r[i] = (long)a[i] * ((n - 1) - i + 1);
				}
				else {
					r[i] = (long)a[i] * ((rightKey - 1) - i + 1) + r[rightKey];
				}
			}
		}
		int max = 0;
		for(int i = 0; i < n; i++) {
			max = Math.max(max, a[i]);
		}
		long ans = 0;
		int maxarg = 0;
		for(int i = 0; i < n; i++) {
			if(a[i] == max) {
				long s = 0;
				if(i - 1 >= 0) {
					s += l[i-1];
				}
				if(i + 1 < n) {
					s += r[i+1];
				}
				s += a[i];
				if(s > ans) {
					ans = s;
					maxarg = i;
				}
			}
		}
		for(int i = maxarg - 1; i >= 0; i--) {
			a[i] = Math.min(a[i], a[i+1]);
		}
		for(int i = maxarg + 1; i < n; i++) {
			a[i] = Math.min(a[i], a[i-1]);
		}
		for(int v : a) out.print(v+" ");
		out.println();
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;

public class Main {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		//Random gen = new Random();
		int n = ni();
		int[] a = na(n);
//		int n = 10;
//		int[] a = new int[n];
//		for(int i = 0; i < n; i++) {
//			a[i] = gen.nextInt(10);
//		}
//		tr(a);
		long[] l = new long[n];
		long[] r = new long[n];
		TreeMap<Integer, Integer> mapLeft = new TreeMap<>();
		TreeMap<Integer, Integer> mapRight = new TreeMap<>();
		for(int i = 0; i < n; i++) {
			mapLeft.put(a[i], i);
			if(i == 0) {
				l[i] = a[i];
				continue;
			}
			if(a[i] >= a[i-1]) {
				l[i] = a[i] + l[i-1];
			}
			else {
				Integer leftKey = mapLeft.lowerKey(a[i]);
				if(leftKey == null) {
					l[i] = (long)a[i] * (i + 1);
				}
				else {
					int ind = mapLeft.get(leftKey);
					l[i] = (long)a[i] * (i - ind) + l[ind];
				}
			}
		}

		for(int i = n-1; i >= 0; i--) {
			mapRight.put(a[i], i);
			if(i == n-1) {
				r[i] = a[i];
				continue;
			}
			if(a[i] >= a[i+1]) {
				r[i] = a[i] + r[i+1];
			}
			else {
				Integer rightKey = mapRight.lowerKey(a[i]);
				if(rightKey == null) {
					r[i] = (long)a[i] * ((n - 1) - i + 1);
				}
				else {
					int ind = mapRight.get(rightKey);
					r[i] = (long)a[i] * ((ind - 1) - i + 1) + r[ind];
				}
			}
		}
		long ans = 0;
		int maxarg = 0;
		for(int i = 0; i < n; i++) {
				long s = 0;
				s = l[i] + r[i];
				s -= a[i];
				if(s > ans) {
					ans = s;
					maxarg = i;
				}
		}
		for(int i = maxarg - 1; i >= 0; i--) {
			a[i] = Math.min(a[i], a[i+1]);
		}
		for(int i = maxarg + 1; i < n; i++) {
			a[i] = Math.min(a[i], a[i-1]);
		}
		for(int v : a) out.print(v+" ");
		out.println();
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;

public class Main {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve() {
//		Random gen = new Random();
		int n = ni();
		int[] a = na(n);
//		int n = 20;
//		int[] a = new int[n];
//		for(int i = 0; i < n; i++) {
//			a[i] = gen.nextInt(1000000000);
//		}
		long[] l = new long[n];
		long[] r = new long[n];
		TreeMap<Integer, Integer> mapLeft = new TreeMap<>();
		TreeMap<Integer, Integer> mapRight = new TreeMap<>();
		for(int i = 0; i < n; i++) {
			mapLeft.put(a[i], i);
			if(i == 0) {
				l[i] = a[i];
				continue;
			}
			if(a[i] >= a[i-1]) {
				l[i] = a[i] + l[i-1];
			}
			else {
				Integer leftKey = mapLeft.lowerKey(a[i]);
				if(leftKey == null) {
					l[i] = (long)a[i] * (i + 1);
				}
				else {
					int ind = mapLeft.get(leftKey);
					l[i] = (long)a[i] * (i - ind) + l[ind];
				}
			}
		}

		for(int i = n-1; i >= 0; i--) {
			mapRight.put(a[i], i);
			if(i == n-1) {
				r[i] = a[i];
				continue;
			}
			if(a[i] >= a[i+1]) {
				r[i] = a[i] + r[i+1];
			}
			else {
				Integer rightKey = mapRight.lowerKey(a[i]);
				if(rightKey == null) {
					r[i] = (long)a[i] * ((n - 1) - i + 1);
				}
				else {
					int ind = mapRight.get(rightKey);
					r[i] = (long)a[i] * ((ind - 1) - i + 1) + r[ind];
				}
			}
		}
		int max = 0;
		for(int i = 0; i < n; i++) {
			max = Math.max(max, a[i]);
		}
		long ans = 0;
		int maxarg = 0;
		for(int i = 0; i < n; i++) {
			if(a[i] == max) {
				long s = 0;
				if(i - 1 >= 0) {
					s += l[i-1];
				}
				if(i + 1 < n) {
					s += r[i+1];
				}
				s += a[i];
				if(s > ans) {
					ans = s;
					maxarg = i;
				}
			}
		}
		for(int i = maxarg - 1; i >= 0; i--) {
			a[i] = Math.min(a[i], a[i+1]);
		}
		for(int i = maxarg + 1; i < n; i++) {
			a[i] = Math.min(a[i], a[i-1]);
		}
		for(int v : a) out.print(v+" ");
		out.println();
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Stack;

public class Main {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve() {

		int n = ni();
		int[] a = na(n);
		int[][] b = minLeftRight(a);
		long[] l = new long[n];
		long[] r = new long[n];
		for(int i = 0; i < n; i++) {
			if(i == 0) {
				l[i] = a[i];
				continue;
			}
			if(a[i] >= a[i-1]) {
				l[i] = a[i] + l[i-1];
			}
			else {
				int left = b[0][i];
				if(left == -1) {
					l[i] = (long)a[i] * (i + 1);
				}
				else {
					l[i] = (long)a[i] * (i - left) + l[left];
				}
			}
		}

		for(int i = n-1; i >= 0; i--) {
			if(i == n-1) {
				r[i] = a[i];
				continue;
			}
			if(a[i] >= a[i+1]) {
				r[i] = a[i] + r[i+1];
			}
			else {
				int right = b[1][i];
				if(right == -1) {
					r[i] = (long)a[i] * ((n - 1) - i + 1);
				}
				else {
					r[i] = (long)a[i] * ((right - 1) - i + 1) + r[right];
				}
			}
		}
		long ans = 0;
		int maxarg = 0;
		for(int i = 0; i < n; i++) {
				long s = 0;
				s = l[i] + r[i];
				s -= a[i];
				if(s > ans) {
					ans = s;
					maxarg = i;
				}
		}
		for(int i = maxarg - 1; i >= 0; i--) {
			a[i] = Math.min(a[i], a[i+1]);
		}
		for(int i = maxarg + 1; i < n; i++) {
			a[i] = Math.min(a[i], a[i-1]);
		}
		for(int v : a) out.print(v+" ");
		out.println();
	}

	public int[][] minLeftRight(int[] a) {
		int n = a.length;
		int[] leftToRight = new int[n];
		int[] rightToLeft = new int[n];
		Arrays.fill(leftToRight, -1);
		Arrays.fill(rightToLeft, -1);
		{
			Stack<Integer> s = new Stack<>();
			for (int i = 0; i < n; i++) {
				if (s.isEmpty()) {
					s.push(i);
				} else {
					int top = s.peek();
					if (a[top] > a[i]) {
						while (!s.isEmpty() && a[s.peek()] > a[i]) {
							leftToRight[s.peek()] = i;
							s.pop();
						}
					}
					s.push(i);
				}
			}
		}
		{
			Stack<Integer> s = new Stack<>();
			for (int i = n - 1; i >= 0; i--) {
				if (s.isEmpty()) {
					s.push(i);
				} else {
					int top = s.peek();
					if (a[top] > a[i]) {
						while (!s.isEmpty() && a[s.peek()] > a[i]) {
							rightToLeft[s.peek()] = i;
							s.pop();
						}
					}
					s.push(i);
				}
			}
		}
		return new int[][] { rightToLeft, leftToRight};
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(isSpaceChar(b))) {
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.*;
import java.util.*;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    int[] arr;
    int[] ans;
    SegmentTreeDS st;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);
        st = new SegmentTreeDS(arr);

        ans = new int[n];

        recurse(0, n-1, true);

        printArray(ans);
    }

    long recurse(int l, int r, boolean update) {
        if(l>r) {
            return 0L;
        }
        Node node = st.query(l, r);

        //System.out.println("Node for " + l + " " + r + ": " + node);
        long val1 = recurse(l, node.minIndex-1, false) + (long) (r-node.minIndex+1)*node.min;

        long val2 = recurse(node.maxIndex+1, r, false) + (long) (node.maxIndex-l+1)*node.min;

        long val3 = 0;

        if (node.minIndex != node.maxIndex) {
            val3 = recurse(node.minIndex + 1, node.maxIndex - 1, false) + (long) (r - node.maxIndex + 1) * node.min
                    + (long) (node.minIndex - l + 1) * node.min;
        }

        long max = Math.max(Math.max(val1, val2), val3);

        if (update) {
            //System.out.print("For " + l + " " + r + "   max: " + max + "  and it is ");
            if(max==val1) {
                //System.out.println("VAL 1");
                for(int i=node.minIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(l, node.minIndex-1, true);
            } else if(max==val2) {
                //System.out.println("VAL 2");
                for(int i=l; i<=node.maxIndex; i++) {
                    ans[i] = node.min;
                }
                recurse(node.maxIndex+1, r, true);
            } else {
                //System.out.println("VAL 3"); lul
                for(int i=l; i<=node.minIndex; i++) {
                    ans[i] = node.min;
                }
                for(int i=node.maxIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(node.minIndex + 1, node.maxIndex - 1, true);
            }
        }

        return max;
    }

    class Node {
        int min; int minIndex; int maxIndex;
        void setLeafNode(int index, int val) {
            min = val; minIndex = index; maxIndex = index;
        }

        void combineNodes(Node a, Node b) {
            if (b.min < a.min) {
                this.min = b.min;
                this.minIndex = b.minIndex;
                this.maxIndex = b.maxIndex;
            } else if (b.min > a.min) {
                this.min = a.min;
                this.minIndex = a.minIndex;
                this.maxIndex = a.maxIndex;
            } else {
                this.min = a.min;
                this.minIndex = Math.min(a.minIndex, b.minIndex);
                this.maxIndex = Math.max(a.maxIndex, b.maxIndex);
            }
        }

        @Override
        public String toString() {
            return " min: " + min + " minIndex: " + minIndex + " maxIndex: " + maxIndex;
        }
    }

    public class SegmentTreeDS {

        /* *********************************** */
        /* CHANGE HERE FOR OTHER FUNCTIONALITY */

        /* CHANGE HERE FOR OTHER FUNCTIONALITY */
        /* *********************************** */

        private final Node[] tree;

        public SegmentTreeDS(int[] arr) {
            int padLen = 1;
            while (padLen < arr.length) padLen <<= 1;
            tree = new Node[2*padLen];
            for (int i = 0; i < arr.length; i++) {
                tree[i+padLen] = new Node();
                tree[i+padLen].setLeafNode(i, arr[i]);
            }
            while (padLen/2 > 0) {
                for (int i = padLen/2; i < padLen; i++) {
                    if (tree[2*i+1] == null) tree[i] = tree[2*i];
                    else {
                        tree[i] = new Node();
                        tree[i].combineNodes(tree[2*i], tree[2*i+1]);
                    }
                }
                padLen /= 2;
            }
        }

        public Node query(int left, int right) {
            left = tree.length/2  + left;
            right = tree.length/2 + right;
            if (left == right) return tree[left];
            Node result = new Node();
            result.combineNodes(tree[left], tree[right]);
            while (left/2 != right/2) {
                if (left % 2 == 0) result.combineNodes(result, tree[left+1]);
                if (right % 2 == 1) result.combineNodes(result, tree[right-1]);
                left /= 2;
                right /= 2;
            }
            return result;
        }

        public void set(int index, int value) {
            index = tree.length/2 + index;
            tree[index].setLeafNode(index-tree.length/2, value);
            while (index/2 > 0) {
                index /= 2;
                if (tree[2*index+1] == null) tree[index] = tree[2*index];
                else tree[index].combineNodes(tree[2*index], tree[2*index+1]);
            }
        }
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


import java.io.*;
import java.util.*;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    int[] arr;
    int[] ans;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);

        ans = new int[n];

        long[] l = new long[n];

        Stack<Integer> stack = new Stack<>();
        for(int i=0; i<n; i++) {
            while(!stack.isEmpty() && arr[stack.peek()]>arr[i]) {
                stack.pop();
            }
            l[i] = stack.isEmpty() ? (long) arr[i]*(i+1) : (l[stack.peek()] + (long) arr[i]*(i-stack.peek()));
            stack.push(i);
        }

        stack = new Stack<>();

        long[] r = new long[n];

        for(int i=n-1; i>=0; i--) {
            while(!stack.isEmpty() && arr[stack.peek()]>arr[i]) {
                stack.pop();
            }
            r[i] = stack.isEmpty() ? (long) arr[i]*(n-i) : (r[stack.peek()] + (long) arr[i]*(stack.peek()-i));
            stack.push(i);
        }

        long max = 0L; int maxIndex = 0;

        for(int i=0; i<n-1; i++) {
            long val = l[i] + r[i] - arr[i];
            if(val>max) {
                max = val;
                maxIndex = i;
            }
        }

        ans[maxIndex] = arr[maxIndex];

        for(int i=maxIndex-1; i>=0; i--) {
            ans[i] = Math.min(arr[i], ans[i+1]);
        }

        for(int i=maxIndex+1; i<n; i++) {
            ans[i] = Math.min(arr[i], ans[i-1]);
        }

        printArray(ans);
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    void printArray(long[] arr) {
        for(long k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


import java.io.*;
import java.util.*;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    int[] arr;
    int[] ans;
    SegmentTreeDS st;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);
        st = new SegmentTreeDS(arr);

        ans = new int[n];

        recurse(0, n-1, true);

        //printArray(ans);
    }

    int[] getRandomArray(int n) {
        Random r = new Random();
        int[] lul = new int[n];
        for(int i=0; i<n; i++) {
            lul[i] = r.nextInt(100000000);
        }
        return lul;
    }
    long recurse(int l, int r, boolean update) {
        if(l>r) {
            return 0L;
        }
        Node node = st.query(l, r);

        //System.out.println("Node for " + l + " " + r + ": " + node);
        int ebenIndexLeft = node.minIndex;
        int ebenIndexRight = node.maxIndex;

        do {
            ebenIndexLeft++;
        } while(ebenIndexLeft<r && arr[ebenIndexLeft]==node.min);

        do {
            ebenIndexRight--;
        } while(ebenIndexRight>l && arr[ebenIndexRight]==node.min);

        long val1 = recurse(l, node.minIndex-1, false) + (long) (r-node.minIndex+1)*node.min;

        long val2 = recurse(node.maxIndex+1, r, false) + (long) (node.maxIndex-l+1)*node.min;

        long val3 = 0;

        if (node.minIndex != node.maxIndex) {
            val3 = recurse(ebenIndexLeft + 1, ebenIndexRight - 1, false) + (long) (r - ebenIndexRight + 1) * node.min
                    + (long) (ebenIndexLeft - l + 1) * node.min;
        }

        long max = Math.max(Math.max(val1, val2), val3);

        if (update) {
            //System.out.print("For " + l + " " + r + "   max: " + max + "  and it is ");
            if(max==val1) {
                //System.out.println("VAL 1");
                for(int i=node.minIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(l, node.minIndex-1, true);
            } else if(max==val2) {
                //System.out.println("VAL 2");
                for(int i=l; i<=node.maxIndex; i++) {
                    ans[i] = node.min;
                }
                recurse(node.maxIndex+1, r, true);
            } else {
                //System.out.println("VAL 3"); lul
                for(int i=l; i<=ebenIndexLeft; i++) {
                    ans[i] = node.min;
                }
                for(int i=ebenIndexRight; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(ebenIndexLeft + 1, ebenIndexRight - 1, true);
            }
        }

        return max;
    }

    class Node {
        int min; int minIndex; int maxIndex;
        void setLeafNode(int index, int val) {
            min = val; minIndex = index; maxIndex = index;
        }

        void combineNodes(Node a, Node b) {
            if (b.min < a.min) {
                this.min = b.min;
                this.minIndex = b.minIndex;
                this.maxIndex = b.maxIndex;
            } else if (b.min > a.min) {
                this.min = a.min;
                this.minIndex = a.minIndex;
                this.maxIndex = a.maxIndex;
            } else {
                this.min = a.min;
                this.minIndex = Math.min(a.minIndex, b.minIndex);
                this.maxIndex = Math.max(a.maxIndex, b.maxIndex);
            }
        }

        @Override
        public String toString() {
            return " min: " + min + " minIndex: " + minIndex + " maxIndex: " + maxIndex;
        }
    }

    public class SegmentTreeDS {

        /* *********************************** */
        /* CHANGE HERE FOR OTHER FUNCTIONALITY */

        /* CHANGE HERE FOR OTHER FUNCTIONALITY */
        /* *********************************** */

        private final Node[] tree;

        public SegmentTreeDS(int[] arr) {
            int padLen = 1;
            while (padLen < arr.length) padLen <<= 1;
            tree = new Node[2*padLen];
            for (int i = 0; i < arr.length; i++) {
                tree[i+padLen] = new Node();
                tree[i+padLen].setLeafNode(i, arr[i]);
            }
            while (padLen/2 > 0) {
                for (int i = padLen/2; i < padLen; i++) {
                    if (tree[2*i+1] == null) tree[i] = tree[2*i];
                    else {
                        tree[i] = new Node();
                        tree[i].combineNodes(tree[2*i], tree[2*i+1]);
                    }
                }
                padLen /= 2;
            }
        }

        public Node query(int left, int right) {
            left = tree.length/2  + left;
            right = tree.length/2 + right;
            if (left == right) return tree[left];
            Node result = new Node();
            result.combineNodes(tree[left], tree[right]);
            while (left/2 != right/2) {
                if (left % 2 == 0) result.combineNodes(result, tree[left+1]);
                if (right % 2 == 1) result.combineNodes(result, tree[right-1]);
                left /= 2;
                right /= 2;
            }
            return result;
        }

        public void set(int index, int value) {
            index = tree.length/2 + index;
            tree[index].setLeafNode(index-tree.length/2, value);
            while (index/2 > 0) {
                index /= 2;
                if (tree[2*index+1] == null) tree[index] = tree[2*index];
                else tree[index].combineNodes(tree[2*index], tree[2*index+1]);
            }
        }
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


import java.io.*;
import java.util.*;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    int[] arr;
    int[] ans;
    SegmentTreeDS st;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);
        st = new SegmentTreeDS(arr);

        ans = new int[n];

        recurse(0, n-1, true);

        printArray(ans);
    }

    int[] getRandomArray(int n) {
        Random r = new Random();
        int[] lul = new int[n];
        for(int i=0; i<n; i++) {
            lul[i] = r.nextInt(100000000);
        }
        return lul;
    }
    long recurse(int l, int r, boolean update) {
        if(l>r) {
            return 0L;
        }
        Node node = st.query(l, r);

        //System.out.println("Node for " + l + " " + r + ": " + node);
        int ebenIndexLeft = node.minIndex;
        int ebenIndexRight = node.maxIndex;

        while(ebenIndexLeft <= r && arr[ebenIndexLeft]==node.min) {
            ebenIndexLeft++;
        }
        ebenIndexLeft--;

        while(ebenIndexRight >= l && arr[ebenIndexRight]==node.min) {
            ebenIndexRight--;
        }
        ebenIndexRight++;

        long val1 = recurse(l, node.minIndex-1, false) + (long) (r-node.minIndex+1)*node.min;

        long val2 = recurse(node.maxIndex+1, r, false) + (long) (node.maxIndex-l+1)*node.min;

        long val3 = 0;

        if (node.minIndex != node.maxIndex) {
            val3 = recurse(ebenIndexLeft + 1, ebenIndexRight - 1, false) + (long) (r - ebenIndexRight + 1) * node.min
                    + (long) (ebenIndexLeft - l + 1) * node.min;
        }

        long max = Math.max(Math.max(val1, val2), val3);

        if (update) {
            //System.out.print("For " + l + " " + r + "   max: " + max + "  and it is ");
            if(max==val1) {
                //System.out.println("VAL 1");
                for(int i=node.minIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(l, node.minIndex-1, true);
            } else if(max==val2) {
                //System.out.println("VAL 2");
                for(int i=l; i<=node.maxIndex; i++) {
                    ans[i] = node.min;
                }
                recurse(node.maxIndex+1, r, true);
            } else {
                //System.out.println("VAL 3");
                for(int i=l; i<=ebenIndexLeft; i++) {
                    ans[i] = node.min;
                }
                for(int i=ebenIndexRight; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(ebenIndexLeft + 1, ebenIndexRight - 1, true);
            }
        }

        return max;
    }

    class Node {
        int min; int minIndex; int maxIndex;
        void setLeafNode(int index, int val) {
            min = val; minIndex = index; maxIndex = index;
        }

        void combineNodes(Node a, Node b) {
            if (b.min < a.min) {
                this.min = b.min;
                this.minIndex = b.minIndex;
                this.maxIndex = b.maxIndex;
            } else if (b.min > a.min) {
                this.min = a.min;
                this.minIndex = a.minIndex;
                this.maxIndex = a.maxIndex;
            } else {
                this.min = a.min;
                this.minIndex = Math.min(a.minIndex, b.minIndex);
                this.maxIndex = Math.max(a.maxIndex, b.maxIndex);
            }
        }

        @Override
        public String toString() {
            return " min: " + min + " minIndex: " + minIndex + " maxIndex: " + maxIndex;
        }
    }

    public class SegmentTreeDS {

        /* *********************************** */
        /* CHANGE HERE FOR OTHER FUNCTIONALITY */

        /* CHANGE HERE FOR OTHER FUNCTIONALITY */
        /* *********************************** */

        private final Node[] tree;

        public SegmentTreeDS(int[] arr) {
            int padLen = 1;
            while (padLen < arr.length) padLen <<= 1;
            tree = new Node[2*padLen];
            for (int i = 0; i < arr.length; i++) {
                tree[i+padLen] = new Node();
                tree[i+padLen].setLeafNode(i, arr[i]);
            }
            while (padLen/2 > 0) {
                for (int i = padLen/2; i < padLen; i++) {
                    if (tree[2*i+1] == null) tree[i] = tree[2*i];
                    else {
                        tree[i] = new Node();
                        tree[i].combineNodes(tree[2*i], tree[2*i+1]);
                    }
                }
                padLen /= 2;
            }
        }

        public Node query(int left, int right) {
            left = tree.length/2  + left;
            right = tree.length/2 + right;
            if (left == right) return tree[left];
            Node result = new Node();
            result.combineNodes(tree[left], tree[right]);
            while (left/2 != right/2) {
                if (left % 2 == 0) result.combineNodes(result, tree[left+1]);
                if (right % 2 == 1) result.combineNodes(result, tree[right-1]);
                left /= 2;
                right /= 2;
            }
            return result;
        }

        public void set(int index, int value) {
            index = tree.length/2 + index;
            tree[index].setLeafNode(index-tree.length/2, value);
            while (index/2 > 0) {
                index /= 2;
                if (tree[2*index+1] == null) tree[index] = tree[2*index];
                else tree[index].combineNodes(tree[2*index], tree[2*index+1]);
            }
        }
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


import java.io.*;
import java.util.*;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    int[] arr;
    int[] ans;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);

        ans = new int[n];

        long[] l = new long[n];

        Stack<Integer> stack = new Stack<>();
        for(int i=0; i<n; i++) {
            while(!stack.isEmpty() && arr[stack.peek()]>arr[i]) {
                stack.pop();
            }
            l[i] = stack.isEmpty() ? (long) arr[i]*(i+1) : (l[stack.peek()] + (long) arr[i]*(i-stack.peek()));
            stack.push(i);
        }

        stack = new Stack<>();

        long[] r = new long[n];

        for(int i=n-1; i>=0; i--) {
            while(!stack.isEmpty() && arr[stack.peek()]>arr[i]) {
                stack.pop();
            }
            r[i] = stack.isEmpty() ? (long) arr[i]*(n-i) : (r[stack.peek()] + (long) arr[i]*(stack.peek()-i));
            stack.push(i);
        }

        long max = 0L; int maxIndex = 0;

        for(int i=0; i<n; i++) {
            long val = l[i] + r[i] - arr[i];
            if(val>max) {
                max = val;
                maxIndex = i;
            }
        }

        ans[maxIndex] = arr[maxIndex];

        for(int i=maxIndex-1; i>=0; i--) {
            ans[i] = Math.min(arr[i], ans[i+1]);
        }

        for(int i=maxIndex+1; i<n; i++) {
            ans[i] = Math.min(arr[i], ans[i-1]);
        }

        printArray(ans);
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    void printArray(long[] arr) {
        for(long k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


import java.io.*;
import java.util.*;
import java.math.BigDecimal;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    final int MOD = 998244353;
    private final long BIG = (long) MOD * MOD * 8L;

    String s;
    boolean DEBUG = true;

    int[] arr;
    int[] ans;
    SegmentTreeDS st;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);
        st = new SegmentTreeDS(arr);

        ans = new int[n];

        recurse(0, n-1, true);

        printArray(ans);
    }

    long recurse(int l, int r, boolean update) {
        if(l>r) {
            return 0L;
        }
        Node node = st.query(l, r);

        //System.out.println("Node for " + l + " " + r + ": " + node);
        long val1 = recurse(l, node.minIndex-1, false) + (long) (r-node.minIndex+1)*node.min;

        long val2 = recurse(node.maxIndex+1, r, false) + (long) (node.maxIndex-l+1)*node.min;

        long val3 = 0;

        if (node.minIndex != node.maxIndex) {
            val3 = recurse(node.minIndex + 1, node.maxIndex - 1, false) + (long) (r - node.maxIndex + 1) * node.min
                    + (long) (node.minIndex - l + 1) * node.min;
        }

        long max = Math.max(Math.max(val1, val2), val3);

        if (update) {
            //System.out.print("For " + l + " " + r + "   max: " + max + "  and it is ");
            if(max==val1) {
                //System.out.println("VAL 1");
                for(int i=node.minIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(l, node.minIndex-1, true);
            } else if(max==val2) {
                //System.out.println("VAL 2");
                for(int i=l; i<=node.maxIndex; i++) {
                    ans[i] = node.min;
                }
                recurse(node.maxIndex+1, r, true);
            } else {
                //System.out.println("VAL 3");
                for(int i=l; i<=node.minIndex; i++) {
                    ans[i] = node.min;
                }
                for(int i=node.maxIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(node.minIndex + 1, node.maxIndex - 1, true);
            }
        }

        return max;
    }

    class Node {
        int min; int minIndex; int maxIndex;
        void setLeafNode(int index, int val) {
            min = val; minIndex = index; maxIndex = index;
        }

        void combineNodes(Node a, Node b) {
            if (b.min < a.min) {
                this.min = b.min;
                this.minIndex = b.minIndex;
                this.maxIndex = b.maxIndex;
            } else if (b.min > a.min) {
                this.min = a.min;
                this.minIndex = a.minIndex;
                this.maxIndex = a.maxIndex;
            } else {
                this.min = a.min;
                this.minIndex = Math.min(a.minIndex, b.minIndex);
                this.maxIndex = Math.max(a.maxIndex, b.maxIndex);
            }
        }

        @Override
        public String toString() {
            return " min: " + min + " minIndex: " + minIndex + " maxIndex: " + maxIndex;
        }
    }

    public class SegmentTreeDS {

        /* *********************************** */
        /* CHANGE HERE FOR OTHER FUNCTIONALITY */

        /* CHANGE HERE FOR OTHER FUNCTIONALITY */
        /* *********************************** */

        private final Node[] tree;

        public SegmentTreeDS(int[] arr) {
            int padLen = 1;
            while (padLen < arr.length) padLen <<= 1;
            tree = new Node[2*padLen];
            for (int i = 0; i < arr.length; i++) {
                tree[i+padLen] = new Node();
                tree[i+padLen].setLeafNode(i, arr[i]);
            }
            while (padLen/2 > 0) {
                for (int i = padLen/2; i < padLen; i++) {
                    if (tree[2*i+1] == null) tree[i] = tree[2*i];
                    else {
                        tree[i] = new Node();
                        tree[i].combineNodes(tree[2*i], tree[2*i+1]);
                    }
                }
                padLen /= 2;
            }
        }

        public Node query(int left, int right) {
            left = tree.length/2  + left;
            right = tree.length/2 + right;
            if (left == right) return tree[left];
            Node result = new Node();
            result.combineNodes(tree[left], tree[right]);
            while (left/2 != right/2) {
                if (left % 2 == 0) result.combineNodes(result, tree[left+1]);
                if (right % 2 == 1) result.combineNodes(result, tree[right-1]);
                left /= 2;
                right /= 2;
            }
            return result;
        }

        public void set(int index, int value) {
            index = tree.length/2 + index;
            tree[index].setLeafNode(index-tree.length/2, value);
            while (index/2 > 0) {
                index /= 2;
                if (tree[2*index+1] == null) tree[index] = tree[2*index];
                else tree[index].combineNodes(tree[2*index], tree[2*index+1]);
            }
        }
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


import java.io.*;
import java.util.*;

/**
 * A simple template for competitive programming problems.
 */
public class Solution {
    //final InputReader in = new InputReader("input.txt");
    final InputReader in = new InputReader(System.in);

    final PrintWriter out = new PrintWriter(System.out);

    int[] arr;
    int[] ans;
    SegmentTreeDS st;
    void solve() {
        int n = in.nextInt();
        arr = in.nextArray(n);
        st = new SegmentTreeDS(arr);

        ans = new int[n];

        recurse(0, n-1, true);

        printArray(ans);
    }

    int[] getRandomArray(int n) {
        Random r = new Random();
        int[] lul = new int[n];
        for(int i=0; i<n; i++) {
            lul[i] = r.nextInt(100000000);
        }
        return lul;
    }
    long recurse(int l, int r, boolean update) {
        if(l>r) {
            return 0L;
        }
        Node node = st.query(l, r);

        //System.out.println("Node for " + l + " " + r + ": " + node);
        int ebenIndexLeft = node.minIndex;
        int ebenIndexRight = node.maxIndex;

        while(ebenIndexLeft <= r && arr[ebenIndexLeft]==node.min) {
            ebenIndexLeft++;
        }
        ebenIndexLeft--;

        while(ebenIndexRight >= l && arr[ebenIndexRight]==node.min) {
            ebenIndexRight--;
        }
        ebenIndexRight++;

        long val1 = recurse(l, node.minIndex-1, false) + (long) (r-node.minIndex+1)*node.min;

        long val2 = recurse(node.maxIndex+1, r, false) + (long) (node.maxIndex-l+1)*node.min;

        long val3 = 0;

        if (node.minIndex != node.maxIndex) {
            val3 = recurse(ebenIndexLeft + 1, ebenIndexRight - 1, false);
            if(ebenIndexRight<=ebenIndexLeft) {
                val3 += (long) (r-l+1)*node.min;
            } else {
                val3 += (long) (r - ebenIndexRight + 1) * node.min
                + (long) (ebenIndexLeft - l + 1) * node.min;
            }
        }

        long max = Math.max(Math.max(val1, val2), val3);

        if (update) {
            //System.out.print("For " + l + " " + r + "   max: " + max + "  and it is ");
            if(max==val1) {
                //System.out.println("VAL 1");
                for(int i=node.minIndex; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(l, node.minIndex-1, true);
            } else if(max==val2) {
                //System.out.println("VAL 2");
                for(int i=l; i<=node.maxIndex; i++) {
                    ans[i] = node.min;
                }
                recurse(node.maxIndex+1, r, true);
            } else {
                //System.out.println("VAL 3");
                for(int i=l; i<=ebenIndexLeft; i++) {
                    ans[i] = node.min;
                }
                for(int i=ebenIndexRight; i<=r; i++) {
                    ans[i] = node.min;
                }
                recurse(ebenIndexLeft + 1, ebenIndexRight - 1, true);
            }
        }

        return max;
    }

    class Node {
        int min; int minIndex; int maxIndex;
        void setLeafNode(int index, int val) {
            min = val; minIndex = index; maxIndex = index;
        }

        void combineNodes(Node a, Node b) {
            if (b.min < a.min) {
                this.min = b.min;
                this.minIndex = b.minIndex;
                this.maxIndex = b.maxIndex;
            } else if (b.min > a.min) {
                this.min = a.min;
                this.minIndex = a.minIndex;
                this.maxIndex = a.maxIndex;
            } else {
                this.min = a.min;
                this.minIndex = Math.min(a.minIndex, b.minIndex);
                this.maxIndex = Math.max(a.maxIndex, b.maxIndex);
            }
        }

        @Override
        public String toString() {
            return " min: " + min + " minIndex: " + minIndex + " maxIndex: " + maxIndex;
        }
    }

    public class SegmentTreeDS {

        /* *********************************** */
        /* CHANGE HERE FOR OTHER FUNCTIONALITY */

        /* CHANGE HERE FOR OTHER FUNCTIONALITY */
        /* *********************************** */

        private final Node[] tree;

        public SegmentTreeDS(int[] arr) {
            int padLen = 1;
            while (padLen < arr.length) padLen <<= 1;
            tree = new Node[2*padLen];
            for (int i = 0; i < arr.length; i++) {
                tree[i+padLen] = new Node();
                tree[i+padLen].setLeafNode(i, arr[i]);
            }
            while (padLen/2 > 0) {
                for (int i = padLen/2; i < padLen; i++) {
                    if (tree[2*i+1] == null) tree[i] = tree[2*i];
                    else {
                        tree[i] = new Node();
                        tree[i].combineNodes(tree[2*i], tree[2*i+1]);
                    }
                }
                padLen /= 2;
            }
        }

        public Node query(int left, int right) {
            left = tree.length/2  + left;
            right = tree.length/2 + right;
            if (left == right) return tree[left];
            Node result = new Node();
            result.combineNodes(tree[left], tree[right]);
            while (left/2 != right/2) {
                if (left % 2 == 0) result.combineNodes(result, tree[left+1]);
                if (right % 2 == 1) result.combineNodes(result, tree[right-1]);
                left /= 2;
                right /= 2;
            }
            return result;
        }

        public void set(int index, int value) {
            index = tree.length/2 + index;
            tree[index].setLeafNode(index-tree.length/2, value);
            while (index/2 > 0) {
                index /= 2;
                if (tree[2*index+1] == null) tree[index] = tree[2*index];
                else tree[index].combineNodes(tree[2*index], tree[2*index+1]);
            }
        }
    }

    void printArray(int[] arr) {
        for(int k : arr) {
            out.print(k + " ");
        }
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException {
        Solution s = new Solution();
        Long t1 = System.currentTimeMillis();
        s.solve();
        System.err.println(System.currentTimeMillis() - t1 + " ms");
        s.out.close();
    }

    public Solution() throws FileNotFoundException {
    }

    private static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        InputReader(InputStream stream) {
            this.stream = stream;
        }

        InputReader(String fileName) {
            InputStream stream = null;
            try {
                stream = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            this.stream = stream;
        }

        int[] nextArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = nextInt();
            return arr;
        }

        int[][] nextMatrix(int n, int m) {
            int[][] matrix = new int[n][m];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                    matrix[i][j] = nextInt();
            return matrix;
        }

        String nextLine() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        int nextInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        double nextDouble() {
            return Double.parseDouble(nextString());
        }

        private int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
    }

}


#include<bits/stdc++.h>
#define maxn (200000)
#define mod (998244353)
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    return x*f;
}
long long gcd(long long x,long long y){return y?gcd(y,x%y):x;}
long long power(long x,long y)
{
	long long t=1;
	for(;y;y>>=1,x=x*x%mod)
		if(y&1)t=t*x%mod;
	return t;
}
long long a[maxn],b[maxn];
int main()
{
	int n=read();
	for(int i=0;i<n;i++)b[i]=read();
	for(int i=0;i<n;i++)if(b[i]<b[(i+1)%n]&&b[i]!=1)
	{
		a[i]=b[i];
		for(int j=i?i-1:n-1;j!=i;j=j?j-1:n-1)
		{
			a[j]=b[j]+a[(j+1)%n];
			if(a[j]<1e9)a[j]+=(1e9/a[(j+1)%n]+1)*a[(j+1)%n]+1;
		}
		cout<<"YES"<<endl;
		for(int j=0;j<n;j++)printf("%I64d ",a[j]);
		cout<<endl;
		return 0;
	}
	if(b[0]==0)
	{
		cout<<"YES"<<endl;
		for(int j=0;j<n;j++)printf("%I64d ",1);
		cout<<endl;
	}else cout<<"NO"<<endl;
	return 0;
}