1. 程式人生 > >[Sdoi 2016] 排列計數

[Sdoi 2016] 排列計數

題意描述:

求有多少種長度為 n 的序列 A,滿足以下條件:

1 ~ n 這 n 個數在序列中各出現了一次

若第 i 個數 A[i] 的值為 i,則稱 i 是穩定的。序列恰好有 m 個數是穩定的

滿足條件的序列可能很多,序列數對 10^9+7 取模。

題目分析:

錯排公式+組合數
答案為 mar[nm]C(n,m)

題目連結:

Ac code :

#include <cstdio>
#include <iostream>
#define ll long long
#define il inline
const int
mod=1e9+7; const int maxm=1000010; ll mar[maxm]={1,0,1}; ll mul[maxm]; il void make() { for(int i=3;i<=maxm;i++) mar[i]=(1ll*(i-1)*(mar[i-1]+mar[i-2])%mod)%mod; mul[0]=1; for(int i=1;i<=maxm;i++) mul[i]=(mul[i-1]*1ll*i)%mod; } il ll fast_pow(ll x,int y) { ll ans=1; while
(y) { if(y%2) ans=(ans*x)%mod; y/=2; x=(x*x)%mod; } return ans%mod; } ll C(int n,int m) { ll x=mul[n]%mod; ll y=mul[m]*mul[n-m]%mod; ll ret=(x*fast_pow(y,mod-2))%mod; return ret; } int main() { freopen("menci_permutation.in","r",stdin); freopen("menci_permutation.out"
,"w",stdout); make(); int q; scanf("%d",&q); while(q--) { int n,m; scanf("%d%d",&n,&m); printf("%lld\n",(mar[n-m]*C(n,m))%mod); } return 0; }