题目链接:https://vjudge.net/problem/Gym-101933K
转自:https://blog.csdn.net/qq_41955236/article/details/83443456
题意:有一棵树,问恰好用k种颜色将相邻节点涂成不相同颜色的方案数。
思路:用二项式反演公式:
#include <bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
long long C[2505][2505],n,k;
long long qsm(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1)
{
ans=ans*a%mod;
}
a=a*a%mod;
b>>=1;
}
return ans;
}
void init()//推组合数公式
{
for(int i=0; i<=2500; i++)
{
C[i][0]=1;
C[i][1]=i;
}
for(int i=1; i<=2500; i++)
{
for(int j=2; j<=i; j++)
{
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
}
}
}
int main()
{
init();
scanf("%lld%lld",&n,&k);
for(int i=1; i<n; i++)
{
long long x;
scanf("%lld",&x);
}
long long ans=0,flag=1;
for(int i=k; i>=1; i--)//二项式反演公式
{
long long aim=flag*i*qsm(i-1,n-1)%mod*C[k][i];
ans=(ans+aim+mod)%mod;
flag=-flag;
}
printf("%lld\n",ans);
return 0;
}