AcWing 886. 预处理阶乘求组合数(模板)

题目链接:点击这里

在这里插入图片描述
C n m = n ! m ! ( n m ) ! C_n^{m}=\frac{n!}{m!(n-m)!}

首先预处理出所有阶乘取模的余数fact[N],以及所有阶乘取模的逆元infact[N]
如果取模的数是质数,可以用费马小定理求逆元

  1. f a c t [ i ] = ( i ! )   m o d   ( 1 e 9 + 7 ) fact[i] = (i!)\ mod \ (1e9+7)
  2. i n f a c t [ i ] = ( i ! ) 1   m o d   ( 1 e 9 + 7 ) infact[i] = (i!)^{-1}\ mod\ (1e9+7)

那么,组合数求解如下:

C n m = f a c t [ n ] i n f a c t [ m ] i n f a c t [ n m ] C_n^{m} = fact[n]*infact[m]*infact[n-m]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;
const int N = 100010, mod = 1e9 + 7;
int fact[N], infact[N];

int qmi(int a, int b, int m)
{
    int res = 1;
    while(b)
    {
        if(b & 1)   res = (ll)res * a % mod;
        a = (ll)a * a % mod;
        b >>= 1;
    }
    return res;
}

int main()
{
    fact[0] = 1, infact[0] = 1;
    for(int i = 1; i < N; ++i)
    {
        fact[i] = (ll)fact[i-1] * i % mod;
        infact[i] = (ll)infact[i-1] * qmi(i, mod-2, mod) % mod;
    }
    
    int n;
    
    scanf("%d", &n);
    
    while(n--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        printf("%d\n", (ll)fact[a] * infact[b] % mod * infact[a-b] % mod);
    }
    
    return 0;
}
发布了811 篇原创文章 · 获赞 127 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104812292