Problem:
Score : 900 points

Problem Statement

You are developing frog-shaped robots, and decided to race them against each other.

First, you placed N robots onto a number line.
These robots are numbered 1 through N.
The current coordinate of robot i is x_i.
Here, all x_i are integers, and 0 < x_1 < x_2 < ... < x_N.

You will repeatedly perform the following operation:

Select a robot on the number line. Let the coordinate of the robot be x. Select the destination coordinate, either x-1 or x-2, that is not occupied by another robot. The robot now jumps to the selected coordinate.

When the coordinate of a robot becomes 0 or less, the robot is considered finished and will be removed from the number line immediately.
You will repeat the operation until all the robots finish the race.

Depending on your choice in the operation, the N robots can finish the race in different orders.
In how many different orders can the N robots finish the race?
Find the answer modulo 10^9+7.

Constraints

2 ≤ N ≤ 10^5

x_i is an integer.

0 < x_1 < x_2 < ... < x_N ≤ 10^9

Partial Score

In a test set worth 500 points, N ≤ 8.

Input

The input is given from Standard Input in the following format:

N
x_1 x_2 ... x_N

Output

Print the number of the different orders in which the N robots can finish the race, modulo 10^9+7.

Sample Input 1

3
1 2 3

Sample Output 1

4

There are four different orders in which the three robots can finish the race:

(Robot 1 → Robot 2 → Robot 3)

(Robot 1 → Robot 3 → Robot 2)

(Robot 2 → Robot 1 → Robot 3)

(Robot 2 → Robot 3 → Robot 1)

Sample Input 2

3
2 3 4

Sample Output 2

6

There are six different orders in which the three robots can finish the race:

(Robot 1 → Robot 2 → Robot 3)

(Robot 1 → Robot 3 → Robot 2)

(Robot 2 → Robot 1 → Robot 3)

(Robot 2 → Robot 3 → Robot 1)

(Robot 3 → Robot 1 → Robot 2)

(Robot 3 → Robot 2 → Robot 1)

For example, the order (Robot 3 → Robot 2 → Robot 1) can be achieved as shown in the figure below:

Sample Input 3

8
1 2 3 5 7 11 13 17

Sample Output 3

10080

Sample Input 4

13
4 6 8 9 10 12 14 15 16 18 20 21 22

Sample Output 4

311014372

Remember to print the answer modulo 10^9+7.
This case is not included in the test set for the partial score.

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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

// modulo integer
// M: modulo number
// * M < 2^31
// * M must be prime if you use division
template <int64_t M> class mint {
public:
  mint() : v(-1) {}
  mint(int n) : v(n % M) {}

  int64_t get() const { return v; }

  mint &operator+=(const mint &r) {
    v = (v + r.v) % M;
    return *this;
  }
  mint &operator-=(const mint &r) {
    v = (v - r.v + M) % M;
    return *this;
  }
  mint &operator*=(const mint &r) {
    v = (v * r.v) % M;
    return *this;
  }
  mint &operator/=(const mint &r) { return (*this) *= r.inv(); }

  mint pow(int r) const {
    mint k = *this, ret = 1;
    while (r > 0) {
      if (r % 2 != 0)
        ret *= k;
      r /= 2;
      k *= k;
    }
    return ret;
  }

  mint inv() const { return pow(M - 2); }

private:
  int64_t v;
};

template <int64_t M> inline mint<M> operator+(mint<M> l, const mint<M> &r) {
  return l += r;
}

template <int64_t M> inline mint<M> operator-(mint<M> l, const mint<M> &r) {
  return l -= r;
}

template <int64_t M> inline mint<M> operator*(mint<M> l, const mint<M> &r) {
  return l *= r;
}

template <int64_t M> inline mint<M> operator/(mint<M> l, const mint<M> &r) {
  return l /= r;
}

template <int64_t M> inline ostream &operator<<(ostream &os, const mint<M> &r) {
  return os << r.get();
}

typedef mint<1000000007> MINT;

bool erase(vector<int> &xs, int pos) {
  if (pos < 2)
    return true;

  for (int i = pos - 1; i - 1 >= 0; i--) {
    if (xs[i] - xs[i - 1] == 1) {
      xs[i - 1]--;
      if (xs[i - 1] <= 0)
        return false;

      int j = i - 1;
      while (j - 1 >= 0 && xs[j] - xs[j - 1] <= 0) {
        xs[j - 1]--;
        if (xs[j - 1] <= 0)
          return false;
        j--;
      }
    }
  }
  return true;
}

int main() {
  cin.tie(0);
  int n;
  cin >> n;

  vector<int> as(n);
  for (auto &a : as)
    cin >> a;

  MINT ans = 1;
  int cur = 0;
  for (int i = 0; i < n; i++) {
    while (cur < n - 1) {
      int t = cur - i + 1;
      if (as[cur] < t * 2 - 1) {
        break;
      }
      cur++;
    }

    // cout << i << ", " << cur << ": " << cur - i + 1 << endl;
    ans *= (cur - i + 1);
  }

  cout << ans << endl;

  return 0;

  /*
    vector<int> perm(n);
    for (int i = 0; i < n; i++)
      perm[i] = i;

    int ans = 0;
    do {
      auto tmp = as;
      bool ok = true;
      auto pm = perm;
      for (int i = 0; i < n; i++) {
        auto p = pm[i];
        if (!erase(tmp, p)) {
          ok = false;
          break;
        }
        //   tmp[perm[i]] = 0x7fffffff;
        for (int j = p; j + 1 < n; j++) {
          tmp[j] = tmp[j + 1];
        }
        for (int j = i + 1; j < n; j++) {
          if (pm[j] > p) {
            pm[j]--;
          }
        }
      }
      if (ok) {
        cout << "* ";
        for (auto &p : perm)
          cout << p + 1 << " ";
        cout << endl;
        ans++;
      }
    } while (next_permutation(perm.begin(), perm.end()));

    cout << ans << endl;

    return 0;
    */
}