Codeforces GYM 100548 F - Color (2014年西安站F题)

来源:互联网 发布:大数据研究现状 编辑:程序博客网 时间:2024/05/29 12:10

题意:N朵花,有M种颜色可用,要求给他们涂色,相邻的话颜色不同。要求正好使用K种颜色。
题解:选K种颜色是Ckm,记F(i)为选了K种颜色后,使用不超过i种颜色的方案。第一朵花有i种选择,后面N1朵的花的颜色除了前一朵花的颜色之外都可以选,总的就是F(i)=Ciki(i1)n1
要求出正好K种颜色的,就要利用容斥原理,用不超过K种的 - 不超过(K1)种的 + 不超过(K2)种的 - 不超过(K3)种的…
答案就是Ckm(F(k)F(k1)+F(k2)...)=Ckmki=1(1)kiF(i)

题目地址
这里写图片描述

#include <iostream>#include <cstring>#include <cstdio>#define prt(k) cout<<#k" = "<<k<<endl;using namespace std;typedef long long ll;const ll mod = 1000000007;const int N = 1000005;ll inv[N];ll C[N];ll n, m, k;ll powmod(ll a, ll n){    ll ret = 1;    for (; n; n>>=1, a=a*a%mod)        if (n&1)        ret = ret*a%mod;    return ret % mod;}void init(ll m, ll k){    C[0] = 1;    for (ll i=1;i<=k;i++)        C[i] = ( C[i-1] * (m-i+1) %mod )* inv[i]% mod;}ll F(ll i){    return (i*C[i] %mod )* powmod(i-1, n-1) % mod;}int main(){    memset(inv, 0, sizeof inv);    for (int i=1;i<N;i++) inv[i] = powmod(i, mod-2)%mod;    int re, ca=1; scanf("%d", &re);    while (re--)    {        scanf("%I64d %I64d %I64d", &n, &m, &k);        ll sig = 1;        init(m, k);        ll ans = C[k]%mod;        ll tmp = 0;        memset(C, 0, sizeof C);        init(k, k);        for (ll i=k;i>=1;i--)        {            tmp = (tmp + sig * F(i) + mod) % mod;            sig = -sig;        }        ans = ans * tmp % mod;        printf("Case #%d: %I64d\n", ca++, ans);    }    return 0;}
2 0
原创粉丝点击