排列計數[luogu4071][逆元][錯排列]
阿新 • • 發佈:2018-12-02
D[i]表示錯排列個數 , 可以證明
然後預處理階乘 , 查詢時逆元搞一波就好了 (這年頭用ex_gcd寫逆元的真少)
#include<bits/stdc++.h> #define N 1000000 #define LL long long #define P 1000000007 using namespace std; LL C[N+50],D[N+50]; int T,n,m; LL x,y; void exgcd(int a,int b){ if(!b){x=1,y=0; return;} exgcd(b,a%b); LL x1=y,y1=x-a/b*y; x=x1,y=y1; } LL inv(int X){ int a=X,b=P; exgcd(a,b); return (x+P)%P; } LL Ask(int x,int y){ return C[x] * inv(C[x-y]) % P * inv(C[y]) % P; } int main(){ C[0]=1 , D[0]=D[2]=1 , D[3]=2; for(int i=1;i<=N;i++) C[i] = (LL)C[i-1] * i % P; for(int i=4;i<=N;i++) D[i] = (LL)(i-1) * (D[i-1] + D[i-2]) % P; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); printf("%lld\n",Ask(n,m) * D[n-m] % P); }return 0; }