题目链接:http://codeforces.com/contest/111/problem/D
题意:给出一个n*m的方格,用K种颜色染色。定义A[i,j]表示第i列到第j列所有格子不同的颜色数。求有多少种染色方案使得所有的1<=i<m,满足A[1,i]=A[i+1,m]?
思路:首先可以得到:
(1)A[1,1]=A[m,m],也就是第一列和最后一列不同的颜色数相同。否则,不妨设A[1,1]<A[m,m],那么A[1,1]<A[2,m]。
(2)设第一列和最后一列相同的颜色数为i,不同的颜色数为j,那么A[1,1]=A[m,m]=i+j。且中间m-2列的格子的所有颜色都是i种颜色中的颜色。
我们用f[i]表示用i种颜色染色n个格子的方案数,那么有:
最后计算答案:
(1)若m=1,ans=K^n;
(2)m>=2,ans=C(K,i)*C(K-i,j)*C(K-i-j,j)*f[i+j]*f[i+j]*pow(i,n*(m-2))。
i64 a[N];
void init()
{
int i;
a[0]=1;
for(i=1;i<N;i++) a[i]=a[i-1]*i%mod;
}
i64 exGcd(i64 a,i64 b,i64 &x,i64 &y)
{
if(b==0)
{
x=1; y=0;
return a;
}
i64 temp=exGcd(b,a%b,x,y);
i64 k=x;
x=y;
y=k-a/b*y;
return temp;
}
i64 reverse(i64 a,i64 b)
{
i64 x,y;
exGcd(a,b,x,y);
x%=b;
if(x<0) x+=b;
return x;
}
i64 C(int n,int m)
{
return a[n]*reverse(a[m]*a[n-m]%mod,mod)%mod;
}
int n,m,K;
i64 f[N];
i64 Pow(i64 a,i64 b)
{
i64 ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init1()
{
f[1]=1;
int i,j;
for(i=2;i<=n;i++)
{
f[i]=Pow(i,n);
for(j=1;j<i;j++) (f[i]-=C(i,j)*f[j]%mod)%=mod;
if(f[i]<0) f[i]+=mod;
}
}
int main()
{
init();
Rush(n)
{
RD(m,K);
if(m==1) PR(Pow(K,n));
else
{
init1();
i64 ans=0,i,j;
for(i=0;i<=n;i++) for(j=0;i+j<=n;j++)
{
if(i==0&&j==0) continue;
if(i+j+j>K) continue;
i64 temp=C(K,i)*C(K-i,j)%mod*C(K-i-j,j)%mod;
temp=temp*f[i+j]%mod*f[i+j]%mod;
temp=temp*Pow(i,n*(m-2))%mod;
ans=(ans+temp)%mod;
}
PR(ans);
}
}
}