Problem:
Score : 1200 points

Problem Statement

One day Mr. Takahashi picked up a dictionary containing all of the N! permutations of integers 1 through N.
The dictionary has N! pages, and page i (1 ≤ i ≤ N!) contains the i-th permutation in the lexicographical order.

Mr. Takahashi wanted to look up a certain permutation of length N in this dictionary, but he forgot some part of it.

His memory of the permutation is described by a sequence P_1, P_2, ..., P_N.
If P_i = 0, it means that he forgot the i-th element of the permutation; otherwise, it means that he remembered the i-th element of the permutation and it is P_i.

He decided to look up all the possible permutations in the dictionary.
Compute the sum of the page numbers of the pages he has to check, modulo 10^9 + 7.

Constraints

1 ≤ N ≤ 500000

0 ≤ P_i ≤ N

P_i ≠ P_j if i ≠ j (1 ≤ i, j ≤ N), P_i ≠ 0 and P_j ≠ 0.

Partial Score

In test cases worth 500 points, 1 ≤ N ≤ 3000.

Input

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

N
P_1 P_2 ... P_N

Output

Print the sum of the page numbers of the pages he has to check, as modulo 10^9 + 7.

Sample Input 1

4
0 2 3 0

Sample Output 1

23

The possible permutations are [1, 2, 3, 4] and [4, 2, 3, 1].
Since the former is on page 1 and the latter is on page 22, the answer is 23.

Sample Input 2

3
0 0 0

Sample Output 2

21

Since all permutations of length 3 are possible, the answer is 1 + 2 + 3 + 4 + 5 + 6 = 21.

Sample Input 3

5
1 2 3 5 4

Sample Output 3

2

Mr. Takahashi remembered all the elements of the permutation.

Sample Input 4

1
0

Sample Output 4

1

The dictionary consists of one page.

Sample Input 5

10
0 3 0 0 1 0 4 0 0 0

Sample Output 5

953330050

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using static System.Console;
using static System.Math;
class E { static void Main() => new K(); }
class K
{
	int F() => int.Parse(ReadLine());
	int[] G() => ReadLine().Split().Select(x => int.Parse(x)).ToArray();
	const long Mod = 1000000007;
	public K()
	{
		var N = F();
		var I = G();
		var p = new int[N];
		var cnt = new int[N + 1];
		for (var i = 0; i < N; i++) cnt[i + 1] = cnt[i] + ((p[i] = I[N - i - 1] - 1) < 0 ? 1 : 0);
		var fact = new long[N + 1];
		fact[0] = 1;
		for (var i = 1; i <= N; i++) fact[i] = i * fact[i - 1] % Mod;
		var M = cnt[N];
		var s = fact[M];
		var bit = new BinaryIndexedTree(N);
		var l = new int[N];
		for (var i = 0; i < N; i++)
		{
			if (p[i] < 0) continue;
			l[i] = bit.Sum(0, p[i]);
			bit.Add(p[i], 1);
		}
		var l2 = new int[N];
		for (var i = 0; i < N; i++) l2[i] = bit.Sum(0, p[i]);
		var h = 1L;
		for (var i = 3; i <= M; i++) h = h * i % Mod;
		var t = new long[N + 1];
		for (var j = 0; j < N; j++) if (p[j] >= 0) t[j + 1] = M - p[j] + l2[j];
		for (var j = 0; j < N; j++) t[j + 1] = (t[j + 1] + t[j]) % Mod;
		for (var i = 1; i < N; i++)
		{
			var c = 0L;
			if (p[i] >= 0)
			{
				c = fact[M] * l[i] % Mod;
				if (M > 0) c = (c + (p[i] - l2[i]) * fact[M - 1] % Mod * cnt[i] % Mod) % Mod;
			}
			else
			{
				c = h * cnt[i] % Mod;
				c = (c + t[i] * fact[M - 1] % Mod) % Mod;
			}
			s = (s + (c * fact[i]) % Mod) % Mod;
		}
		WriteLine(s);
	}
}
class BinaryIndexedTree
{
	public int Size;
	int[] bit;
	public BinaryIndexedTree(int size) { Size = size; bit = new int[size + 1]; }
	public void Add(int index, int value) { for (var i = index + 1; i <= Size; i += i & (-i)) bit[i] += value; }
	public int Sum(int from, int to) => Sum(to) - Sum(from);
	int Sum(int to) { var sum = 0; for (var i = to; i > 0; i -= i & (-i)) sum += bit[i]; return sum; }
}