1. 程式人生 > >Gym101194 H Great Cells

Gym101194 H Great Cells

一堆人做出來了,就我不會做,感覺我完全不會計數題啊,菜的雅痞。還好最後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;
}