UVALive 7040

这道题我和队友磨了好久。。。写到后面其他题都没什么时间了,再加上一个队友没来,另一个队友1点半才来,我中途出去送一趟课堂考勤表。今天测试成绩很烂。。。

这题关键是恰好选出k种颜色,就是用k种颜色涂n个格子,每个颜色至少涂一个,彼此不相邻,的答案再乘c(m,k)。以前HNOI有道水题就是用k种颜色涂色,然后彼此不相邻,答案就是k*(k-1)^(n-1),这是有可能用,2,3,4,...k种不同的颜色涂满的情况之和,于是就要减去由(k-1)种颜色涂满这n个格子的和,C(k,k-1)*(k-1)*(k-2)^(n-1),然而由于从k种中选出k-1种,这个式子也是表示k-1,k-2,k-3...2种去涂的数量的总和,k-2又重复了,于是这就是一个容斥问题了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>

using namespace std;

typedef long long LL;
const int maxl=1e6+50;
const LL mod=1e9+7;

LL C[maxl];

LL qp(LL a,LL b)
{
    LL ans=1,cnt=a;
    while(b)
    {
        if(b&1)
            ans=(ans*cnt)%mod;
        cnt=(cnt*cnt)%mod;
        b>>=1;
    }
    return ans;
}

LL ck(LL k)
{
    LL zi=1,mu=1;
    for(LL i=1;i<=k;i++)
    {
        zi=(zi*(k-i+1))%mod;
        mu=(mu*i)%mod;
        C[i]=(zi*qp(mu,mod-2))%mod;
    }
}

LL c(LL m,LL k)
{
    LL zi=1,mu=1;
    for(LL i=1;i<=k;i++)
    {
        zi=(zi*(m-i+1))%mod;
        mu=(mu*i)%mod;
    }
    return (zi*qp(mu,mod-2))%mod;
}

LL n,m,k;

int main()
{
    int T;cin>>T;
    for(int kas=1;kas<=T;++kas){
        scanf("%lld%lld%lld",&n,&m,&k);
        ck(k);
        LL ans=k*qp(k-1,n-1)%mod,tmp;
        for(int i=1;k-i>=2;++i){
            tmp = ((C[k-i]*(k-i))%mod)*qp(k-i-1,n-1)%mod;
            if(i&1)ans=(mod+ans-tmp)%mod;
            else ans=(ans+tmp)%mod;
        }
        ans=ans*c(m,k)%mod;
        printf("Case #%d: %lld\n",kas,ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值