#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
namespace fast_scanner {
static char ibuf[1 << 20], *p1 = ibuf, *p2 = ibuf;
bool advance() { return p2 = (p1 = ibuf) + fread(ibuf, 1, sizeof(ibuf), stdin), (p1 == p2); }
char gc() { return (p1 == p2 && advance()) ? EOF : (*p1++); }
void put_back() { p1--; }
static bool isspace(char c) { return static_cast<unsigned char>(c - '\t') < 5 || c == ' '; }
static bool isdigit(char c) { return static_cast<unsigned char>(c - '0') < 10; }
static inline bool isoneof(char c, const char *str) { return strchr(str, c) != nullptr; }
template <const char *str> static inline bool isoneof(char c) { return strchr(str, c) != nullptr; }
uint64_t read_ull() {
    char ch = gc();
    while (!isdigit(ch)) {
        ch = gc();
    }
    uint64_t res = 0;
    while (isdigit(ch)) {
        res = res * 10 + (ch - '0'), ch = gc();
    }
    return res;
}
int64_t read_ll() {
    char ch = gc();
    bool neg = false;
    while (!isdigit(ch)) {
        neg |= (ch == '-'), ch = gc();
    }
    uint64_t res = 0;
    while (isdigit(ch)) {
        res = res * 10 + (ch - '0'), ch = gc();
    }
    neg && (res = -res);
    return res;
}
long double read_ld() {
    char ch = gc();
    bool neg = false;
    while (!isdigit(ch)) {
        neg |= (ch == '-'), ch = gc();
    }
    uint64_t integerPart = 0, fractionalPart = 0, len = 0, base = 1;
    while (isdigit(ch)) {
        integerPart = integerPart * 10 + (ch - '0'), ch = gc();
    }
    if (ch == '.') {
        ch = gc();
        while (isdigit(ch)) {
            fractionalPart = fractionalPart * 10 + (ch - '0'), ch = gc(), len += 1;
        }
        while (len--)
            base *= 10;
    }
    long double res = (long double)integerPart + (long double)fractionalPart / base;
    neg && (res = -res);
    return res;
}
string read_delim(const char *str) {
    char ch = gc();
    while (isoneof(ch, str))
        ch = gc();
    string res;
    while (!isoneof(ch, str))
        res += ch, ch = gc();
    return res;
}
template <typename UnaryPredicate> string read_delim(UnaryPredicate predicate) {
    char ch = gc();
    while (predicate(ch))
        ch = gc();
    string res;
    while (!predicate(ch))
        res += ch, ch = gc();
    return res;
}
string read_line() {
    return read_delim([](char ch) {
        return ch == '\n';
    });
}
string read_string() { return read_delim(isspace); }
char read_char() { return gc(); }
int read_int() { return (int)read_ll(); }
void skip_whitespace() {
    char ch = gc();
    while (isspace(ch))
        ch = gc();
    put_back();
}
}
template <typename T> T scan();
template <> int scan<int>() { return fast_scanner::read_int(); }
template <> long scan<long>() { return (long)fast_scanner::read_ll(); }
template <> long long scan<long long>() { return fast_scanner::read_ll(); }
template <> long double scan<long double>() { return fast_scanner::read_ld(); }
template <> double scan<double>() { return (double)fast_scanner::read_ld(); }
template <> string scan<string>() { return fast_scanner::read_string(); }
template <> char scan<char>() { return fast_scanner::gc(); }
void scan() { fast_scanner::skip_whitespace(); }
template <typename A, typename B> pair<A, B> scan() {
    auto a = scan<A>();
    auto b = scan<B>();
    return make_pair(a, b);
}
template<typename A, typename B, typename C> tuple<A, B, C> scan() {
    auto a = scan<A>();
    auto b = scan<B>();
    auto c = scan<C>();
    return make_tuple(a, b, c);
}
template <typename A, typename B, typename C, typename D, typename... Args> tuple<A, B, C, Args...> scan() {
    auto a = make_tuple(scan<A>());
    auto b = scan<B, C, D, Args...>();
    return tuple_cat(a, b);
}
template <typename T, size_t U> array<T, U> scan() {
    array<T, U> res;
    for (size_t i = 0; i < U; ++i)
        res[i] = scan<T>();
    return res;
}
template <typename T> vector<T> scan(int n, int s = 0) {
    vector<T> res(n + s);
    for (int i = 0; i < n; ++i) {
        res[i + s] = scan<T>();
    }
    return res;
}
template <typename A, typename B> vector<pair<A, B>> scan(int n, int s = 0) {
    vector<pair<A, B>> res(n + s);
    for (int i = 0; i < n; ++i) {
        res[i + s] = scan<A, B>();
    }
    return res;
}
template <typename A, typename B, typename C, typename... Args> vector<tuple<A, B, C, Args...>> scan(int n, int s = 0) {
    vector<tuple<A, B, C, Args...>> res(n + s);
    for (int i = 0; i < n; ++i) {
        res[i + s] = scan<A, B, C, Args...>();
    }
    return res;
}
template <typename T, size_t U> vector<array<T, U>> scan(int n, int s = 0) {
    vector<array<T, U>> res(n + s);
    for (size_t i = 0; i < U; ++i)
        res[i + s] = scan<T, U>();
    return res;
}
template <typename T, size_t X> void ctvl(T (&a)[X], const T &v) { fill_n(&a[0], X, v); }
template <typename T, size_t X, size_t Y> void ctvl(T (&a)[X][Y], const T &v) { fill_n(&a[0][0], X * Y, v); }
template <typename T, size_t X, size_t Y, size_t Z> void ctvl(T (&a)[X][Y][Z], const T &v) { fill_n(&a[0][0][0], X * Y * Z, v); }
template <typename T, size_t X, size_t Y, size_t Z, size_t W> void ctvl(T (&a)[X][Y][Z][W], const T &v) { fill_n(&a[0][0][0][0], X * Y * Z * W, v); }
template <typename T> T read() { T x; cin >> x; return x; }
template <typename... Args> void writeln(const Args &... args) { ((cout << args << " "), ...), cout << endl; }
template <typename... Args> void write(const Args &... args) { ((cout << args), ...); }
template <typename T> typename enable_if<is_same<decltype(declval<T>().size()), size_t>::value, int>::type operator~(const T &ct) { return (int)ct.size(); }
template <typename T, typename... Args> bool ckmax(T &a, const Args &... b) { return (a < max({b...})) ? (a = max({b...}), true) : false; }
template <typename T, typename... Args> bool ckmin(T &a, const Args &... b) { return (a > min({b...})) ? (a = min({b...}), true) : false; }
template <typename T> T div_floor(const T &a, const T &b) { return (a / b) - (!!(a % b) & ((a ^ b) < 0)); }
template <typename T> T div_ceil(const T &a, const T &b) { return (a / b) + (!!(a % b) & ((a ^ b) > 0)); }
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T, typename... Args, template <typename, typename...> typename Container> Container<T, Args...> &operator+=(Container<T, Args...> &ct, const T &val) { return ct.push_back(val), ct; }
template <typename T, typename... Args, template <typename, typename...> typename Container> Container<T, Args...> &operator+=(const T &val, Container<T, Args...> &ct) { return ct.push_front(val), ct; }
template <typename T, typename... Args, template <typename, typename...> typename Container> T &operator+(Container<T, Args...> &ct) { return *ct.begin(); }
template <typename T, typename... Args, template <typename, typename...> typename Container> T &operator-(Container<T, Args...> &ct) { return *prev(ct.end()); }
template <typename T, typename... Args, template <typename, typename...> typename Container> T operator--(Container<T, Args...> &ct) { auto res = *ct.begin(); return ct.erase(ct.begin()), res; }
template <typename T, typename... Args, template <typename, typename...> typename Container> T operator--(Container<T, Args...> &ct, int) { auto res = *prev(ct.end()); return ct.erase(prev(ct.end())), res; }
template <typename T, typename... Args, template <typename, typename...> typename Container> int lbi(const Container<T, Args...> &ct, const T &val) { return (int)(lower_bound(ct.begin(), ct.end(), val) - ct.begin()); }
template <typename T, typename... Args, template <typename, typename...> typename Container> int ubi(const Container<T, Args...> &ct, const T &val) { return (int)(upper_bound(ct.begin(), ct.end(), val) - ct.begin()); }
template <int D, typename T> struct vecnd : public vector<vecnd<D - 1, T>> {
    template <typename... Args> vecnd(int n, Args... args) : vector<vecnd<D - 1, T>>(n, vecnd<D - 1, T>(args...)) {}
    void fill(const T &val = T()) {
        for (auto &it : *this)
            it.fill(val);
    }
    bool bounds_check(int i) { return (i >= 0) and (i < (int)this->size()); }
    template <typename... Args> bool bounds_check(int i, Args... args) {
        return (i >= 0) and (i < (int)this->size()) and (this->at(i).bounds_check(args...));
    }
};
template <typename T> struct vecnd<1, T> : public vector<T> {
    vecnd(int n, const T &val = T()) : vector<T>(n, val) {}
    void fill(const T &val = T()) {
        for (auto &it : *this)
            it = val;
    }
    bool bounds_check(int i) { return (i >= 0) and (i < (int)this->size()); }
};
template <typename T> using V = vecnd<1, T>;
template <typename T> using VV = vecnd<2, T>;
template <typename T> using VVV = vecnd<3, T>;
vector<pair<int, int>> dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
vector<pair<int, int>> edirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
template <typename K, typename V> pair<K, V> operator+(const pair<K, V> &a, const pair<K, V> &b) { return {a.first + b.first, a.second + b.second}; }
template <typename K, typename V> pair<K, V> operator-(const pair<K, V> &a, const pair<K, V> &b) { return {a.first - b.first, a.second - b.second}; }
template <typename K, typename V> pair<K, V>& operator+=(pair<K, V> &a, const pair<K, V> &b) { return a = a + b; }
template <typename K, typename V> pair<K, V>& operator-=(pair<K, V> &a, const pair<K, V> &b) { return a = a - b; }
template <typename T> struct range { T u, v;
    range(const T &_u, const T &_v) : u(_u), v(_v) {}
    bool has(const T &w) { return (u <= w) and (w < v); }
    bool has_incl(const T &w) { return (u <= w) and (w <= v); }
};
int log2_floor(uint32_t n) { return 31 - __builtin_clz(n); }
int log2_ceil(uint32_t n) { return log2_floor(n) + !!(n & (n - 1)); }
       
template <typename T> using vv = vector<vector<T>>;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
auto soln() {
    int n = scan<int>();
    auto x = scan<int>(n, 1);
    vector<pair<int, int> > y(n + 1);
    for (int i = 1; i <= (int)(n); ++i) y[i] = {x[i], i};
    vector<int> order(n + 1);
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(), [&](int i, int j) {return x[i] < x[j];});
    int m = n*n;
    vector<int> res(m + 1);
    int left=1, right=m;
    for(int i = 1; i <= n; ++i) { res[x[i]] = i; }
    for(int p = 1; p <= n; ++p) {
        int i = order[p];
        int cntl = i-1;
        while(cntl) {
            if(left >= x[i]) { ;; return cout << "No" << "\n", 0;}
            if(!res[left]) res[left++] = i, cntl--;
            else left++;
        }
    }
    for(int p = n; p >= 1; --p) {
        int i = order[p];
        int cntr = n - i;
        while(cntr) {
            if(right <= x[i]) { ;; return cout << "No" << "\n", 0; }
            if(!res[right]) res[right--] = i, cntr--;
            else right--;
        }
    }
    cout << "Yes" << "\n";
    for(int i = 1; i <= m; ++i) {
        cout << res[i] << " \n"[i == m];
    }
    return 0;
}
signed main() {
    int t = 1;
    ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
    while (t--)
        soln();
    return 0;
}


Measured memory_bytes: 4260