Problem:
Score : 300 points

Problem Statement

Given is an integer sequence D_1,...,D_N of N elements. Find the number, modulo 998244353, of trees with N vertices numbered 1 to N that satisfy the following condition:

For every integer i from 1 to N, the distance between Vertex 1 and Vertex i is D_i.

Notes

A tree of N vertices is a connected undirected graph with N vertices and N-1 edges, and the distance between two vertices are the number of edges in the shortest path between them.

Two trees are considered different if and only if there are two vertices x and y such that there is an edge between x and y in one of those trees and not in the other.

Constraints

1 \leq N \leq 10^5

0 \leq D_i \leq N-1

Input

Input is given from Standard Input in the following format:

N
D_1 D_2 ... D_N

Output

Print the answer.

Sample Input 1

4
0 1 1 2

Sample Output 1

2

For example, a tree with edges (1,2), (1,3), and (2,4) satisfies the condition.

Sample Input 2

4
1 1 1 1

Sample Output 2

0

Sample Input 3

7
0 3 2 1 2 2 1

Sample Output 3

24

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef vector<int> vint;
typedef pair<int, int> pint;
#define CPP_STR(x) CPP_STR_I(x)
#define CPP_CAT(x, y) CPP_CAT_I(x, y)
#define CPP_STR_I(args...) #args
#define CPP_CAT_I(x, y) x##y
#define ASSERT(expr...) assert((expr))

/* type annotation */
using i8 = int8_t;
using u8 = uint8_t;
using i16 = int16_t;
using u16 = uint16_t;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
using f32 = float;
using f64 = double;
constexpr i64 INF = 1'010'000'000'000'000'017LL;
constexpr i64 MOD = 1'000'000'007LL;
constexpr f64 EPS = 1e-12;
constexpr f64 PI = 3.14159265358979323846;

/* macros */
#define FOR(i, start, end)                             \
    for(i64 i = (start), CPP_CAT(i, xxxx_end) = (end); \
        i < CPP_CAT(i, xxxx_end); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(f, c, ...)                                               \
    (([&](decltype((c)) cccc) {                                      \
        return (f)(std::begin(cccc), std::end(cccc), ##__VA_ARGS__); \
    })(c))
template <typename C>
i64 SIZE(const C &c) {
    return static_cast<i64>(c.size());
}
template <typename T, size_t N>
i64 SIZE(const T (&)[N]) {
    return static_cast<i64>(N);
}
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())

/* marathon match */
#ifdef LOCAL
const i64 CYCLES_PER_SEC = 2800000000;
#else
const i64 CYCLES_PER_SEC = 2800000000;  // AtCoder
#endif

struct Timer {
    i64 start;

    Timer() { reset(); }

    void reset() { start = getCycle(); }

    inline double get() {
        return (double)(getCycle() - start) / CYCLES_PER_SEC * 1000;
    }

   private:
    inline i64 getCycle() {
        u32 low, high;
        __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
        return ((i64)low) | ((i64)high << 32);
    }
} timer;

class XorShift {
   public:
    unsigned int x, y, z, w;
    double nL[65536];

    XorShift() { init(); }

    void init() {
        x = 314159265;
        y = 358979323;
        z = 846264338;
        w = 327950288;
        double n = 1 / (double)(2 * 65536);
        for(int i = 0; i < 65536; i++) {
            nL[i] = log(((double)i / 65536) + n);
        }
    }

    inline unsigned int next() {
        unsigned int t = x ^ x << 11;
        x = y;
        y = z;
        z = w;
        return w = w ^ w >> 19 ^ t ^ t >> 8;
    }

    inline double nextLog() { return nL[next() & 0xFFFF]; }

    inline int nextInt(int m) { return (int)(next() % m); }

    int nextInt(int min, int max) { return min + nextInt(max - min + 1); }

    inline double nextDouble() { return (double)next() / ((long long)1 << 32); }
} rnd;

struct IoSetup {
    IoSetup() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(20);
        cerr << fixed << setprecision(20);
    }
} iosetup;

/* keep a max,min */
template <typename T, typename U, typename Comp = less<>>
bool chmax(T &xmax, const U &x, Comp comp = {}) {
    if(comp(xmax, x)) {
        xmax = x;
        return true;
    }
    return false;
}

template <typename T, typename U, typename Comp = less<>>
bool chmin(T &xmin, const U &x, Comp comp = {}) {
    if(comp(x, xmin)) {
        xmin = x;
        return true;
    }
    return false;
}

/* input,output operator for pair, vector and map */

/* input,output operator for pair and vector */
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os << p.first << " " << p.second;
    return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    for(int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 != v.size() ? " " : "");
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &v) {
    for(int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 != v.size() ? "\n" : "");
    }
    return os;
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for(T &in : v) is >> in;
    return is;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &mp) {
    os << "{";
    for(auto x = mp.begin(); x != mp.end(); ++x) {
        os << x->first << ":" << x->second << (x != prev(mp.end()) ? ", " : "");
    }
    os << "}";
    return os;
}

using std::to_string;

auto to_string(std::string s) -> std::string { return s; }

auto to_string(char c) -> std::string { return std::string{c}; }

auto to_string(const char *s) -> std::string {
    return to_string((std::string)s);
}

auto to_string(bool b) -> std::string { return (b ? "true" : "false"); }

template <typename T, typename U>
auto to_string(std::pair<T, U> p) -> std::string {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <size_t N>
auto to_string(std::bitset<N> bs) -> std::string {
    std::string res{};
    for(size_t i = 0; i < N; i++)
        res.insert(res.begin(), bs.test(i) ? '1' : '0');
    return res;
}

template <typename T>
auto to_string(T v) -> std::string {
    bool flg = false;
    std::string res = "[";
    for(auto const &x : v) {
        if(flg)
            res += ", ";
        else
            flg = true;
        res += to_string(x);
    }
    res += "]";
    return res;
}

/* initialize vector. usage: auto v = make_v<int>(N,0); */
template <typename T>
vector<T> make_v(size_t a) {
    return vector<T>(a);
}

template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

/* fill vector. usage: fill_v(v,0); */
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
    t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
    for(auto &e : t) fill_v(e, v);
}

template <std::uint_fast32_t MODULO>
struct modint {
   private:
    using uint32 = std::uint_fast32_t;
    using uint64 = std::uint_fast64_t;

   public:
    uint32 a;
    modint() : a(0) {}
    modint(const std::int_fast64_t &x) : a(set(x % MODULO + MODULO)) {}
    static uint32 set(const uint32 &x) { return (x < MODULO) ? x : x - MODULO; }
    static modint make(const uint32 &x) {
        modint ret;
        ret.a = x;
        return ret;
    }
    modint operator+(const modint &o) const { return make(set(a + o.a)); }
    modint operator-(const modint &o) const {
        return make(set(a + MODULO - o.a));
    }
    modint operator*(const modint &o) const {
        return make((uint64)a * o.a % MODULO);
    }
    modint operator/(const modint &o) const {
        return make((uint64)a * ~o % MODULO);
    }
    modint &operator+=(const modint &o) { return *this = *this + o; }
    modint &operator-=(const modint &o) { return *this = *this - o; }
    modint &operator*=(const modint &o) { return *this = *this * o; }
    modint &operator/=(const modint &o) { return *this = *this / o; }
    modint &operator^=(const uint32 &o) { return *this = *this ^ o; }
    modint operator~() const { return *this ^ (MODULO - 2); }
    modint operator-() const { return make(set(MODULO - a)); }
    modint operator++() { return *this = make(set(a + 1)); }
    modint operator--() { return *this = make(set(a + MODULO - 1)); }
    bool operator==(const modint &o) const { return a == o.a; }
    bool operator!=(const modint &o) const { return a != o.a; }
    bool operator<(const modint &o) const { return a < o.a; }
    bool operator<=(const modint &o) const { return a <= o.a; }
    bool operator>(const modint &o) const { return a > o.a; }
    bool operator>=(const modint &o) const { return a >= o.a; }
    explicit operator bool() const { return a; }
    explicit operator uint32() const { return a; }
    modint operator^(uint32 x) const {
        uint64 t = a, u = 1;
        while(x) {
            if(x & 1) u = u * t % MODULO;
            t = (t * t) % MODULO;
            x >>= 1;
        }
        return make(u);
    }
};

using mint = modint<998244353>;

void solve() {
    auto ng = [](int i) {
        cout << i << endl;
        exit(0);
    };
    i64 N;
    cin >> N;
    vector<i64> D(N);
    cin >> D;

    if(D[0] != 0) ng(0);

    mint ans(1);
    vector<int> dict(N, 0);
    for(auto x : D) dict[x]++;
    if(dict[0] > 1) ng(0);
    REP(i, N - 1) { ans *= mint(dict[i]) ^ dict[i + 1]; }
    cout << ans.a << endl;
}

int main() {
    /* main code */
    solve();
    return 0;
}