组合数学习+组合数取模+牛客网第六场C. Generation I(组合数学)+逆元的两种方法模板

C(n,m)性质:
1.C(n,m)=C(n,n-m)=C(n-1,m-1)+C(n-1,m);
设S(n,m)=C(n,0)+C(n,1)+……+C(n,m),则
2.S(n,m) = S(n,m-1) +C(n,m);
3.S(n,m) = 2*S(n-1,m) - C(n-1,m);
4.S(n-1,m)=(S(n,m)+C(n-1,m))/2;(可由1推出);

组合数取模模板:
C(n,m)=Comb(n,m);

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn =1e5+5;
const int mod = 1e9+7;
LL fac[maxn],inv[maxn];//inv[maxn]  为maxn的阶乘的逆元,fac[maxn]为maxn的阶乘
LL rev2;
LL qpow(LL b,int n){
    LL res=1;
    while(n){
        if(n&1) res=res*b%mod;
        b = b*b%mod;
        n>>=1;
    }
    return res;
}

LL Comb(int n,int k)
{
    return fac[n]*inv[k]%mod *inv[n-k]%mod;
}

void pre()
{
    rev2 = qpow(2,mod-2);
    fac[0]=fac[1]=1;
    for(int i=2;i<maxn;++i) fac[i]=i*fac[i-1]%mod;
    inv[maxn-1]=qpow(fac[maxn-1],mod-2);
    for(int i=maxn-2;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
}

组合数其他的性质:
已知A(m,i)求A(m,i+1):
A(m,i+1)=A(m,i)*(m-i);
已知C(n,j)求C(n,j+1):
C(n,j+1)=C(n,j)*(n-1)/(j+1);

牛客网第六场C. Generation I(组合数学)
题目链接:
https://www.nowcoder.com/acm/contest/144/C

//这里求逆元不能打阶乘表,数据过大;
代码:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn = int(1e6) + 100;
const LL mod = 998244353;
LL inv[maxn] = { 1,1 };
//O(N)打印逆元表
void init() {
    for (LL i = 2; i<maxn; i++) {
        inv[i] = (mod - mod / i)*inv[mod%i] % mod;
    }
}
int main() {
    init();
    int T, kase = 1;
    scanf("%d", &T);
    while (T--) {
        LL n, m;
        scanf("%lld%lld", &n, &m);
        LL ans = 0;
        LL A = m % mod, C = 1;//第一项
        for (LL i = 1, j = 0; i <= m && j <= n-1; i++,j++) {
            ans = (ans + A * C%mod) % mod;
            A = (m - i) % mod*A%mod;//(m - i)和A的顺序不能反过来,因为m-i是没取模状态的
            C = (n - j - 1) % mod*C%mod*inv[j + 1] % mod;
        }
        printf("Case #%d: %lld\n", kase++, ans);
    }
    return 0;
}

逆元的两种方法:
【1】打阶乘表法(数据过大时不能使用);
【2】线性递推

  inv[1] = 1;
    for(i=2;i<MOD;++i) inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD; // (isprime(MOD))

猜你喜欢

转载自blog.csdn.net/wuxiaowu547/article/details/81352310
今日推荐