[bzoj4517][SDOI2016]排列计数

题目大意

计算C(n,m) * D(n-m)
其中D(x)为错位排列

题目解答

没有什么好说的,注意细节。

代码

#include <bits/stdc++.h>
const int P = 1e9+7;
const int maxn = 1e7+1;
#define ll long long
int D[maxn+10], fact[maxn+10];
int pow(int x, int y) {
    int ans = 1;
    while(y) {
        if(y & 1) ans = (ll) ans * x % P;
        x = (ll) x * x % P;
        y >>= 1;
    }
    return ans;
}
int inv(int n) {
    return pow(n, P-2);
}
int C(int n, int m) {
    return (ll)fact[n] * inv(fact[n-m]) % P * (ll) inv(fact[m]) % P;
}
int main() {
    D[0] = D[2] = 1;
    for(int i = 3; i < maxn; i++) 
        D[i] = (ll)(i-1)*(D[i-1]+D[i-2])%P;
    fact[0]= 1;
    for(int i = 1; i < maxn; i++) 
        fact[i] = (ll)fact[i-1]*i%P;

    int T;
    scanf("%d", &T);
    while(T--) {
        int n, m;
        scanf("%d %d", &n, &m);
        printf("%lld\n", (ll)D[n-m] * C(n, m) % P);
    }
    return 0;
}

posted on 2017-01-24 17:56  蒟蒻konjac  阅读(203)  评论(0编辑  收藏  举报