Gym101194 H Great Cells

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liufengwei1/article/details/82889452

一堆人做出来了,就我不会做,感觉我完全不会计数题啊,菜的雅痞。还好最后qt想出来了,不然要凉。

看似值域为1-k,然后求恰好有g个greatcell很像多校里面jls的一道题,然而这个限制更多,对于一个g已经这么难求了,而对于所有g我感觉简直冇得任何办FA。

于是继上次遇到那个输出X^3次方的套路后,这题的套路又在他要输出的答案上,对 (g+1)Ag 求和拆成2个部分,sigma Ag就是所有的方案数了,因为一个任意放的方案数对对应形成一个Ag的一个方案,所有的放法就是k^nm

然后就是sigma (g*Ag)这个转换是真的关键,对于一种形成Ag的方案,要乘上一个g,也就是这个方案里面的g个greatcells计了一遍数,那么我们从另外一个角度考虑,对于一个格子,如果他是greatcell,对于他是greatcell的所有方案数,他都要计一次数,那么就问题变成了有多少方案中,这个格子要计数,这样就简单很多了,假设他放的是i,那么n-1+m-1个格子智能放1到i-1,而其余的(n-1)*(m-1)个格子还是1-k随便放的,那么这个格子放颜色i时候的贡献就是(i-1)^(n-1+m-1)*k^((n-1)*(m-1)),而对于n*m个格子,这个贡献都是一样的,那么直接乘就好

#include<bits/stdc++.h>
#define maxl 201
#define mod 1000000007

int n,m,k,cas;
long long ans;

inline void prework()
{
	scanf("%d%d%d",&n,&m,&k);
}

inline long long qp(long long a,long long b)
{
	long long ans=1,cnt=a;
	while(b)
	{
		if(b&1)
			ans=(ans*cnt)%mod;
		cnt=(cnt*cnt)%mod;
		b>>=1;
	}
	return ans;
}

inline void mainwork()
{
	ans=qp(k,n*m);
	long long tmp=0;
	for(int i=1;i<=k;i++)
		tmp=(tmp+qp(i-1,n-1+m-1))%mod;
	tmp=tmp*qp(k,(n-1)*(m-1))%mod;
	ans=(ans+tmp*n%mod*m%mod)%mod;
}

long long print()
{
	printf("Case #%d: %lld\n",cas,ans);
}

int main()
{
	int t;
	scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/82889452
今日推荐