2014-2015 ACM-ICPC, Asia Xian Regional Contest F Color

2014-2015 ACM-ICPC, Asia Xian Regional Contest F Color

题意

n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数。

思路

组合计数+容斥(奇加偶减)

公式为 ∑ i = 1 k ( − 1 ) k − i ∗ C ( k , i ) ∗ ( i ) ∗ ( i − 1 ) n − 1 \sum_{i=1}^k(-1)^{k-i}*C(k,i)*(i)*(i-1)^{n-1} i=1k(1)kiC(k,i)(i)(i1)n1 (容斥也忘记了,留坑).

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const int mod=1e9+7;
ll jc[maxn],jcinv[maxn];
int C(int n,int m){
    return jc[n]*jcinv[m]%mod*jcinv[n-m]%mod;
}
ll ksm(long long a,int b){
    long long c=1;
    for(;b;b>>=1){
        if(b&1) c=c*a%mod;
        a=a*a%mod;
    }
    return c;
}
void init(){
    jc[0]=1;jcinv[0]=1;
    for(int i=1;i<=1000000;i++){
        jc[i]=jc[i-1]*i%mod;
        jcinv[i]=ksm(jc[i],mod-2);
    }
}
ll f(ll m,ll k){
    if(k>m) return 0;
    ll ans=1;
    for(int i=1;i<=k;i++){
        ans=ans*(m-i+1)%mod*ksm(i,mod-2)%mod;
    }
    return ans;
}
int main(){
    // printf("%d\n",0%2);
    // printf("%lld %lld\n",f(5,1),f(5,3));
    init();
    // printf("%d")
    int _;scanf("%d",&_);
    int id=0;
    
    while(_--){
        int n,m,k;scanf("%d%d%d",&n,&m,&k);
        ll ans=0;
        // printf("ans=%lld\n",ans);
        ll flag=1;
        for(int i=1;i<=k;i++){
            // printf("%d\n",C(k,i));
            ll tmp=i*ksm(i-1,n-1)%mod;
            // printf("tmp=%lld\n",tmp);
            if((k-i)%2==0) ans=((ans+tmp*C(k,i))%mod+mod)%mod;
            else ans=((ans-tmp*C(k,i))%mod+mod)%mod;
            // flag*=-1;
        }
        printf("Case #%d: %lld\n",++id,ans*f(m,k)%mod);
    }
    //system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值