[SDOI2016] 排列計數 (組合數學)
阿新 • • 發佈:2018-09-14
... sin name splay 兩個 solution .cn define getchar()
在這裏擺一下組合及錯排的公式
\[C_{n}^{m}=\frac{n!}{m!\times{(n-m)!}}\]
\[D_{n}=(n-1)\times(D_{n-1}+D_{n-2})\]
其實錯排還有一個通項公式,但是由於時間復雜度太高,所以預處理不太常用,但在這裏還是擺一下
\[D_{n}=n!(1-\frac{1}{1!}+\frac{1}{2!}-\frac{1}{3!}+...+(-1)^n\frac{1}{n!})\]
[SDOI2016]排列計數
題目描述
求有多少種長度為 n 的序列 A,滿足以下條件:
1 ~ n 這 n 個數在序列中各出現了一次
若第 i 個數 A[i] 的值為 i,則稱 i 是穩定的。序列恰好有 m 個數是穩定的
滿足條件的序列可能很多,序列數對 10^9+7109+7 取模。
輸入輸出格式
輸入格式:
第一行一個數 T,表示有 T 組數據。
接下來 T 行,每行兩個整數 n、m。
輸出格式:
輸出 T 行,每行一個數,表示求出的序列數
輸入輸出樣例
輸入樣例#1:
5
1 0
1 1
5 2
100 50
10000 5000
輸出樣例#1:
0
1
20
578028887
60695423
說明
測試點 1 ~ 3: \(T = 1000,n \leq 8,m \leq 8;\)
測試點 4 ~ 6: \(T = 1000,n \leq 12,m \leq 12;\)
測試點 7 ~ 9: \(T = 1000,n \leq 100,m \leq 100;\)
測試點 10 ~ 12:\(T = 1000,n \leq 1000,m \leq 1000;\)
測試點 13 ~ 14:\(T = 500000,n \leq 1000,m \leq 1000;\)
測試點 15 ~ 20:\(T = 500000,n \leq 1000000,m \leq 1000000。\)
Solution
錯排公式/組合計數 裸題
\(Ans=C_{n}^{m}\times D_{n-m}\),其中\(D_{i}\)為共i個元素的錯排方案數(錯排指元素i不在下標為i的位置上)
然後因為要取模,費馬小定理求一下逆元
\[C_{n}^{m}=\frac{n!}{m!\times{(n-m)!}}\]
\[D_{n}=(n-1)\times(D_{n-1}+D_{n-2})\]
其實錯排還有一個通項公式,但是由於時間復雜度太高,所以預處理不太常用,但在這裏還是擺一下
\[D_{n}=n!(1-\frac{1}{1!}+\frac{1}{2!}-\frac{1}{3!}+...+(-1)^n\frac{1}{n!})\]
Code
#include<bits/stdc++.h> #define Min(a,b) (a)<(b)?(a):(b) #define Max(a,b) (a)>(b)?(a):(b) #define rg register #define il inline #define lol long long using namespace std; const int N=1e6+10,mod=1e9+7; void in(int &ans) { ans=0; int f=1; char i=getchar(); while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();} while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar(); ans*=f; } int T,n,m; lol D[N],ie[N],sum[N];//ie[]是逆元數組,inverse element的簡稱 lol qpow(lol a,int x,lol ans=1) { while(x) { if(x&1) ans=ans*a%mod; x>>=1,a=a*a%mod; }return ans; } il void init() { D[0]=D[2]=1; for(rg int i=3;i<=N;i++) D[i]=(i-1)*(D[i-1]+D[i-2])%mod; ie[0]=sum[0]=1; for(rg int i=1;i<=N;i++) sum[i]=sum[i-1]*i%mod,ie[i]=qpow(sum[i],mod-2); } int main() { in(T); init(); while(T--) { in(n),in(m); printf("%lld\n",D[n-m]*sum[n]%mod*ie[m]%mod*ie[n-m]%mod); } return 0; }
博主蒟蒻,隨意轉載.但必須附上原文鏈接
http://www.cnblogs.com/real-l/
[SDOI2016] 排列計數 (組合數學)