UVALive 7040 Color -二项式反演

二项式反演裸题+组合数递推
思路待补充


#include "bits/stdc++.h"

#define int long long
const int maxn = 1e5 + 10;
const int MAXN = 1e6 + 10;
const int mod = 1e9 + 7;
using namespace std;
void Exgcd(int a, int b, int &x, int &y)
{
    
    
    if(b == 0)
    {
    
    
        x = 1;
        y = 0;
        return;
    }
    int x1, y1;
    Exgcd(b, a%b, x1, y1);
    x = y1;
    y = x1 - (a/b)*y1;
}
int Inv[MAXN];///放逆元的数组
///得到逆元
void Get_Inv()
{
    
    
    Inv[1] = 1;
    for(int i=2; i<MAXN; i++)
    {
    
    
        int y;
        Exgcd(i, mod, Inv[i], y);
        Inv[i] = (Inv[i]%mod+mod)%mod;
    }
}
int quick_pow(int x, int b) {
    
    
    int base = 1;
    while (b) {
    
    
        if (b & 1) {
    
    
            base = (base * x) % mod;
        }
        x = (x * x) % mod;
        b >>= 1;
    }
    return base;
}
int n, m, k;
int cm[MAXN];
int ck[MAXN];
void Get_Fac()
{
    
    
    cm[0] = ck[0] = 1;
    for(int i=1; i<=k; i++)
    {
    
    
        cm[i] = (cm[i-1]%mod * (m-i+1)%mod * Inv[i]%mod) % mod;
        ck[i] = (ck[i-1]%mod * (k-i+1)%mod * Inv[i]%mod) % mod;
    }
}

signed main() {
    
    
//    freopen("in.txt","r",stdin);
    int T;
    cin >> T;
    Get_Inv();
    int id = 0;
    while (T--) {
    
    
        cin >> n >> m >> k;
        int t = 0;
        Get_Fac();
        for (int i = 1; i <= k; ++i) {
    
    
            t = ( t + quick_pow(-1, k - i) * ck[i] * i % mod * quick_pow(i - 1, n - 1) + mod) % mod;
        }
        printf("Case #%lld: %lld\n",++id,t * cm[k] % mod);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45509601/article/details/118853449