Gym101933K 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);
}