bzoj 4487: [Jsoi2015]染色问题

简述题意:

bzoj 4487: [Jsoi2015]染色问题_第1张图片

算法:组合数+容斥(不好推)

难度:NOIP+ 

题解:

首先,你可以用O(nmc)的时间复杂度水过这道题!

公式为:

我是不会告诉你这公式很好推的,反正我自己推不出来,看完题解,大概可能明白了吧

 

如果你不甘心于水过这道题,你可以对上面的公式进行优化,优化成时间复杂度为O(n*m*logc)

推导过程如下:

①<=>②(只是调换了\sum的顺序...)

又因为

所以,综合②③式可得, 

因此,利用 ④式,就可以在O(nmlogc)的时间复杂度内,解决这道题!

代码如下:

#include 
#define ll long long
#define N 405
using namespace std;
const ll p=1000000007;
ll inv[N],jc[N];
void ny()
{
	inv[0]=1;
	inv[1]=1;
	for(int i = 2;i <= 400;i++)
	{
		inv[i]=(p-p/i)*inv[p%i]%p;
	}
	jc[1]=1;
	for(int i = 2;i <= 400;i++)
	{
		jc[i]=((jc[i-1]%p)*i)%p;
	}
	for(int i = 2;i <= 400;i++)
	{
		inv[i]=(inv[i-1]*inv[i])%p;
	}
}
ll powermod(ll x,ll y)
{
	ll ret=1;
	while(y)
	{
		if(y%2)
		{
			ret=ret*x%p;
		}
		y=y/2;
		x=x*x%p;
	}
	return ret;
}
ll C(int n, int m)
{
    return jc[n]*inv[m]%p*inv[n-m]%p;
}
ll ans;
int main()
{
	int n,m,kk;
	scanf("%d%d%d",&n,&m,&kk);
	ny();
	for (int i = 0;i <= n;i++)
	{
		for (int k = 0;k <= kk;k++)
         {
             ll qwq=C(n,i)*C(kk,k)%p;
             ll orz=powermod((1-powermod(k+1,i)+p)%p,m);
             qwq=qwq*orz%p;
             if ((n+m+kk-i-k)%2) qwq=-qwq;
             ans=(ans+qwq)%p;
         }
	}     
    printf("%lld\n",(ans+p)%p);
	return 0 ;
}

 

你可能感兴趣的:(数学)