Gym 101933 King's Colors

Link
设用\(k\)种颜色给\(n\)个点的树染色(必须全用)的方案数为\(f(k)\),用\(k\)种颜色给\(n\)个点的树染色(可以缺用)的方案数为\(g(k)\)
显然有\(g(k)=k(k-1)^{n-1}=\sum\limits_{i=2}^k{k\choose i}f(i)\),直接二项式反演即可。

#include<cstdio>
using i64=long long;
const int N=2507,P=1000000007;
int read(){int x;scanf("%d",&x);return x;}
int f[N],fac[N],ifac[N];
int inc(int a,int b){return (a+b)%P;}
int dec(int a,int b){return (a-b+P)%P;}
int pow(int a,int k){int r=1;for(;k;k>>=1,a=1ll*a*a%P)if(k&1)r=1ll*a*r%P;return r;}
int C(int n,int m){return 1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
int main()
{
    int n=read(),k=read(),ans=0;
    fac[0]=1;
    for(int i=1;i<=k;++i) fac[i]=1ll*fac[i-1]*i%P;
    ifac[k]=pow(fac[k],P-2);
    for(int i=k;i;--i) ifac[i-1]=1ll*ifac[i]*i%P;
    for(int i=2;i<=k;++i) f[i]=1ll*i*pow(i-1,n-1)%P;
    for(int i=1;i<=k;++i) ans=((k-i)&1? dec:inc)(ans,1ll*C(k,i)*f[i]%P);
    printf("%d",ans);
}

猜你喜欢

转载自www.cnblogs.com/cjoierShiina-Mashiro/p/12239715.html
今日推荐