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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

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

@SuppressWarnings("unchecked")
public class Main implements Runnable {

  static BufferedReader in;
  static PrintWriter out;

  public static long totalWays(int a, int b, int MOD) {
    long ans=1L;
    for(int j=1;j<=b;j++) {
      ans*=a;
      ans%=MOD;
    }
    return ans;
  }
 
  public static void main(String[] args) {
      new Thread(null, new Main(), "whatever", 1<<29).start();
  }
 
  public void run() {
    in = new BufferedReader(new InputStreamReader(System.in));
    out = new PrintWriter(System.out, false);
 
    try
    {
      // in = new BufferedReader(new FileReader("class_treasurer.txt"));
      // out = new PrintWriter("output.txt");

      int t,x1,n,i,MOD=998244353;
      String str;
      String[] token;

      str=in.readLine().trim();
      token=str.split(" ");
      n=Integer.parseInt(token[0]);

      int[] d=new int[n];
      int[] cnt=new int[n];

      int max=0;

      str=in.readLine().trim();
      token=str.split(" ");

      for(i=0;i<n;i++) {
        d[i]=Integer.parseInt(token[i]);
        cnt[d[i]]++;
        max=Math.max(max,d[i]);
      }

      boolean possible=true;
      long ways=1L;

      for(i=0;i<=max;i++) {
        if(i==0) {
          if(cnt[i]!=1) {
            possible=false;
            break;
          }
        }
        else {
          if(cnt[i]==0) {
            possible=false;
            break;
          }
          else {
            ways*=totalWays(cnt[i-1],cnt[i],MOD);
            ways%=MOD;
          }
        }
      }

      if(d[0]!=0)
        out.println(0);
      else if(!possible)
        out.println(0);
      else
        out.println(ways);

      out.flush();
      out.close();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
}