Gym101933K King's Colors

Link
设用(k)种颜色给(n)个点的树染色(必须全用)的方案数为(f(k)),用(k)种颜色给(n)个点的树染色(可以缺用)的方案数为(g(k))
显然有(g(k)=k(k-1)^{n-1}=sumlimits_{i=2}^k{kchoose 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);
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12239715.html