It is found that many solutions fail to explain why the inverse element and recurrence formula are used in this problem. I, wind and rain 30 years, just to write a good problem. Let me help you.
Main idea:
A sequence whose length is n and 1~n occurs once respectively is expected to find out the number of sequences under the condition that "there are only m numbers in the sequence whose value is equal to its position". The answer is to model 100000007.
Topic analysis:
This problem may be an enhanced version of "misplaced envelope". Just play with Billy on the "misplaced envelope". We may set:
The number whose value is equal to the position is stable
The value is not equal to the position, the number is unstable
A stable number is incremented from the left to the right of the sequence because it is necessary to ensure that the value is equal to the position
First of all, we can know according to the idea of combination number:
Answer = number of stable selection methods multiplied by number of unstable selection methods.
So now our goal is to find out the number of stable and unstable selection methods.
Number of stable selection methods:
We have known that the stable numbers are increasing from left to right, so we only need to simulate which numbers are stable.
It is not hard to think that the number is actually the number of schemes selected from n numbers.
Isn't this the \ (C ^ m \) in combinatorial numbers? There are \ (C_n^m\) = \(\frac{n!}{m!(n-m)!} \)
Settle
Number of unstable selection methods (staggered):
If we have known which m numbers are stable, we can only look at the unstable numbers in the array for the time being.
That is to say, wrong arrangement
We make the array \ (F_x \) have X numbers, and each number is an unstable method number.
Since these numbers are unstable, there is no incremental relationship between the values, so we need to discuss the classification of each \ (F_x \).
\[suppose a number k, with n in the K position: \begin{cases} When k is in the N position & \ text {the number of permutations is $f {n-2} $(because the position of K has been determined, that is, the number of permutations of the remaining n-2 numbers)}\ When k is not in the nth position & \ text {the number of permutations is $f {n-1} $} \end{cases}\]
So for each \ (f {I \), there are \ (f {X-1} \) = (I - 1) × (\ (f {X-1} \) + \ (f {X-2} \)
So the final answer is: (\ (C {m \ times \) \ (f {N-M} \)% Mod
Specific operation ideas:
We need to initialize first. We need to initialize factorials for \ (C ^ y \) and recurs for \ (f ^ I \).
Then, for each set of data, set (\ (C {m \ times \) \ (f {N-M} \))% mod.
But (not over yet):
According to the meaning of the question, the number of final solutions may be very large (so we need to take modulus). When we multiply the answers, the accuracy of (\ (C ᦉ m \ times \) \ (f {N-M} \)% mod may explode, so we need to use:
Inverse element (inv)
What is inverse element (inv)?
For example, when there is (a/b)%MOD, it can prevent B from being too large and explosive, and convert a/b to some simple multiplication.
If C is the inverse of B, then there is (b * c) ≡ 1 (mod module)
Then (a/b)%mod = (a/b)1%mod = (a/b)bc%mod = (ac)%mod
That is (one number divided by another number)% modulus = (one number multiplied by the inverse of another number)% modulus
How to apply inverse element to the problem
We initialize the inverse element array inv, inv is the inverse element of factorial
So for a fixed value in modulus, how to find the inverse of that value?
Please refer to Fermat's theorem
Give the answer directly: for the inverse of a% 100000007, it is \ (a ^ {100000007-2} \)
Just get a fast power
Code:
#include<bits/stdc++.h> #include<cctype> #pragma GCC optimize(2) #define Max(a,f) a > b ? a : b #define Min(a,b) a < b ? a : b #define in(n) n = read() #define out(a) write(a) #define outn(a) out(a),putchar('\n') #define New ll #define ll long long #define rg register using namespace std; namespace IO_Optimization//Optimization function { inline New read()//Fast reading { New X = 0,w = 0; char ch = 0; while(!isdigit(ch)) { w |= ch == '-'; ch=getchar(); } while(isdigit(ch)) { X = (X << 3) + (X << 1) + (ch ^ 48); ch = getchar(); } return w ? -X : X; } inline void write(New x)//Fast transfusion { if(x < 0) putchar('-'),x = -x; if(x > 9) write(x / 10); putchar(x % 10 + '0'); } } using namespace IO_Optimization; const int mod = 1000000000 + 7;//modulus const int MAXN = 1000000 + 2;//Array size constant ll a[MAXN],f[MAXN],inv[MAXN]; // Factorial F array inverse element array inline ll ksm(ll a,ll b){//Fast power function, inverse element ll ans = 1; a %= mod; while(b) { if(b & 1) ans = (a * ans) % mod; a = (a * a) % mod; b >>= 1; } return ans; } int main() { a[0] = 1;//Initialization for(rg int i = 1;i <= MAXN; ++i) { a[i] = (a[i - 1] * i) % mod;//Remember to take the mold. inv[i] = ksm(a[i],mod - 2);//Computational inverse element } f[1] = 0,f[2] = 1,f[3] = 2;//Initialization for(rg int i = 4;i <= MAXN; ++i) f[i] = ((i - 1) * (f[i - 1] + f[i - 2])) % mod;//Recurrence formula int T = read();//Multiple data input while(T--) { int n = read(),m = read(),k = n - m;//Input n, m, k is purely convenient if(!k)//If n-m=0, the number of schemes is 1 { puts("1"); continue; } if(m == 0)//If there is no stable number, then the answer is directly equal to F[n] { outn(f[n]); continue; } if(k == 1)//If n-m=1, there are 0 schemes { puts("0"); continue; } outn(((( a[n] * inv[k] ) % mod * inv[m]) % mod * f[k]) % mod);//output //It's the inverse of multiplication instead of division } return 0; }