+\lemma
+The function~$n_0$ also satisfies the following recurrence:
+$$
+n_0(z-1,d) = n_0(z,d) + n_0(z-1,d-1) \quad\hbox{for $z>0$, $d>0$.} \eqno{(\maltese)}
+$$
+
+\proof
+We will again take advantage of having proven Lemma~\ref{submatrixlemma}, which
+allows us to choose arbitrary matrices with the given parameters. Let us pick a~matrix~$M_z$
+containing $z$~zeroes such that $M_z[1,1]=0$. Then define~$M_{z-1}$ which is equal to~$M_z$
+everywhere except $M_{z-1}[1,1]=1$.
+
+We will count the permutations $\pi\in {\cal P}_d$ satisfying~$M_{z-1}$ in two ways.
+First, there are $n_0(z-1,d)$ such permutations. On the other hand, we can divide
+the them to two types depending on whether $\pi[1]=1$. Those having $\pi[1]\ne 1$
+are exactly the $n_0(z,d)$ permutations satisfying~$M_z$. The others correspond to
+permutations $(\pi[2],\ldots,\pi[d])$ on $\{2,\ldots,d\}$ that satisfy~$M_z^{1,1}$,
+so there are $n_0(z-1,d-1)$ of them.
+\qed
+
+\cor\id{nzeroprecalc}%
+For a~given~$n$, a~table of the values $n_0(z,d)$ for all $0\le z\le d\le n$
+can be precomputed in time~$\O(n^2)$.
+
+\proof
+Use either recurrence and induction on~$z+d$.
+\qed
+
+\cor\id{smalldiff}%
+For every $0\le z<d$ we have $n_0(z,d) - n_0(z+1,d) \le n_0(z,d)/d$.
+
+\proof
+According to the recurrence $(\maltese)$, the difference $n_0(z,d) - n_0(z+1,d)$ is
+equal to $n_0(z,d-1)$. We can bound this by plugging the trivial inequality $n_0(z,d-1) \le n_0(z-1,d-1)$
+to~$(*)$, from which we obtain $n_0(z,d) \ge d\cdot n_0(z,d-1)$.
+\qed
+
+\para\id{rrankmod}%
+Let us show how to modify the ranking algorithm (\ref{rrankalg}) using the insight
+we have gained into the structure of derangements.
+
+The algorithm uses the matrix~$M$ only for computing~$N_0$ of its submatrices
+and we have shown that this value depends only on the order of the matrix and
+the number of zeroes in it. We will therefore replace maintenance of the matrix
+by remember the number~$z$ of its zeroes and the set~$Z$ that contains the elements
+$x\in A$ whose locations are restricted (there is a~zero anywhere in the $(R_A(x)+1)$-th
+column of~$M$). In other words, every $x\in Z$ can appear at all positions in the
+permutation except one (and these forbidden positions are different for different~$x$'s),
+while the remaining elements of~$A$ can appear anywhere.
+
+As we already observed (\ref{hatcheck}) that the number of derangements on~$[n]$ is $\Theta(n!)$,
+we can again use word-sized vectors to represent the sets~$A$ and~$Z$ with insertion,
+deletion, ranking and unranking on them in constant time.
+
+When the algorithm selects a~submatrix $M'=M^{1,k}$ for an~element $x$ of~rank~$k-1$, this
+matrix it is described by either by the choice of $z'=z-1$ and~$Z'=Z\setminus\{x\}$ (if $x\in Z$)
+or $z'=z$ and $Z'=Z$ (if $x\not\in Z$).
+All computations of~$N_0$ in the algorithm can therefore be replaced by looking
+up the appropriate $n_0(z',\vert A\vert-1)$ in the precomputed table. Moreover, we can
+calculate a~single~$C_a$ in constant time, because all summands are either $n_0(z,\vert A\vert-1)$
+or $n_0(z-1,\vert A\vert-1)$ depending on the set~$Z$. We get:
+$$C_a = r\cdot n_0(z-1,\vert A\vert-1) + (a-r) \cdot n_0(z,\vert A\vert-1),$$
+where $r=R_Z(R^{-1}_A(a))$, that is the number of restricted elements among the $a$~smallest ones in~$A$.
+
+All operations at a~single level of the \<Rank> function now run in constant time,
+but \<Unrank> needs to search among the~$C_a$'s to find the first of them which
+exceeds the given rank. We could use binary search, but that would take $\Theta(\log n)$
+time. There is however a~clever trick: the value of~$C_a$ does not vary too much with
+the set~$Z$. Specifically, by Corollary~\ref{smalldiff} the difference between the values
+for $Z=\emptyset$ and $Z=A$ is at most $n_0(z-1,\vert A\vert -1)$. It is therefore
+sufficient to just divide the rank by $n_0(z-1,\vert A\vert-1)$ and we get either
+the correct value of~$a$ or one more. Both possibilities can be checked in constant time.
+
+We can therefore conclude this section by the following theorem:
+
+\thmn{Ranking of derangements}%
+For every~$n$, the derangements on the set~$[n]$ can be ranked and unranked according to the
+lexicographic order in time~$\O(n)$ after spending $\O(n^2)$ on initialization of auxiliary tables.
+
+\proof
+We modify the general algorithms for (un)ranking of restricted permutations (\ref{rrankalg} and \ref{runrankalg})
+as described above (\ref{rrankmod}). Each of the $n$~levels of recursion will then run in constant time. The values~$n_0$ will
+be looked up in a~table precalculated in quadratic time as shown in Corollary~\ref{nzeroprecalc}.
+\qed