C. Iahub and Permutationstime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard output
Distinct integers,,...,NAILimit ≤ limitN). She replaces some of permutation elements with-1 value as a revenge.
KWhich has value equal to kAKSignature = SignatureK). Your job is to proof to Iahub that trying to recover it is not a good idea. output the number of permutations which cocould be originally Iahub's important permutation, modulo (Limit + limit 7 ).
Input
(NLimit ≤ limit 2000). On the second line, there are nIntegers, representing Iahub's important permutation after Iahubina replaces some values with-1.
Output
Sample test (s) input
OutputNote
-1-1 4 3-15
-1-1 2 5-1
I started to read the legendary frog's blog, indicating that I had never been able to understand it for a night. If the food was a tear! After reading and asking, I finally understood the essentials and thanked frog1902 for his explanation. Address: C. Iahub and Permutations
Obviously, all the positions that have been filled can be ignored. Let's just look at the location where a [I] =-1.
X indicates the number of locations that make a [I] =-1 and the number I has been filled in a certain position. It is called an unlimited position.
Y indicates the number of locations that make a [I] =-1 and the number I is not specified in a specific position. It is called a restricted position.
At the very beginning, we should discard the restriction position of the y.
Because a [I] =-1 and I have not appeared in any position, it will not be affected if you ignore it.
Now we need to fill in x unrestricted positions first.
Because there are x numbers of a [I] =-1, but the number I has been used. So there must be x numbers of a [I]! =-1, but the number I is not used yet.
Place the unused numbers in the specified positions. The number of methods is x! .
Now we can add one or more unrestricted y positions.
Use d [I] to indicate how many unrestricted locations have been added, and do not violate the rules of the wrong sorting.
Apparently d [0] = x! . All we need is d [y].
If we add the I-th restricted position at this time. It can be divided into the following situations:
1) We can find a j from x unrestricted positions so that a [I] = a [j], a [j] = I. Number of protocols to d [I-1.
-1-1 2 5-1
2) We can find a position j from an I-1 restricted position, so that a [I] = j, a [j] = I. Number of protocols to d [I-2.
-1-1 3 4-1
3) We can find a position j from an I-1 restricted position, so that a [I] = j, but a [j]! = I. Number of protocols to d [I-1. It is equivalent to the original d [j]! = J limit changed to d [j]! = I. Other restrictions remain unchanged.
-1-1 3 4-1
AC code:
# Include <iostream> # include <cstring> # include <cmath> # include <cstdio> using namespace std; int mod = 1e9 + 7 ;__ int64 d [2002]; int a [2002] ;__ int64 cal (int p) {_ int64 ans = 1; int I; for (I = 2; I <= p; I ++) ans = (ans * I) % mod; return ans;} int main () {int n, x, y; while (~ Scanf ("% d", & n) {int cnt = 0, t = 0; // The number of records that can be filled in, t The number occupied by the number entered in the record for (int I = 1; I <= n; I ++) {scanf ("% d", & a [I]); if (a [I] =-1) cnt ++;} for (int I = 1; I <= n; I ++) {if (a [I]> 0) {if (a [a [I] =-1) t ++ ;}} x = t; // x is an unlimited number y = cnt-t; d [0] = cal (x); // d [0] = x! For (int I = 1; I <= y; I ++) {d [I] = (x + i-1) * d [I-1]) % mod; if (I> 1) d [I] = (d [I] + (I-1) * d [I-2]) % mod;} printf ("% I64d \ n ", d [y]);} return 0 ;} /* 5-1-1 4 3-15-1-1 4-1-15-1-1 2 5-1 */