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

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

題意

n個格子排成一行,有m種顏色,問用恰好k種顏色進行染色,使得相鄰格子顏色不同的方案數。

思路

組合計數+容斥(奇加偶減)

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

代碼

#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");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章