Problem H. Great Cells
Input file:
Output file:
Time limit:
Standard Input
Standard Ouptut
2 seconds
Mr. Panda likes playing puzzles with grid paper. Recently he invented a new rule to play withthe grid paper.
At the beginning, he grabs a grid paper with N rows and M columns. Then he fills each cell aninteger in the range of [1,K]. After filling all the cells, he starts finding Great cells in the grid. Acell is called Great cell if and only if it meets the following 2 conditions:
• The value in the cell is strictly larger than other cells in the same row.
• The value in the cell is strictly larger than other cells in the same column.
Now Mr. Panda is wondering how many different ways he can fill the grid paper so that there areexactly g Great cells.
As Mr. Panda likes simple conclusion number, let’s just tell him the value
g=0
Ag represents the number of different ways Mr. Panda can fill the grid paper such that there are
exactly g Great cells.Input
The first line of the input gives the number of test cases, T. T lines follow.
Each line represents a test case containing 3 integers N, M representing the number of rows and
columns of the grid paper, K representing the range for filling numbers.Output
For each test case, first output one line containing “Case #x: y”, where x is the test case number(starting from 1), y is the simple conclusion number for Mr. Panda.
Limits
• 1 ≤ T ≤ 20.
• 1≤N,M,K≤200.
NM
∑9(g+1)·Ag mod (10 +7)
Page 11 of 21
The 2016 ACM-ICPC Asia China-Final Contest
Sample input and output
Note
Forthefirstsample,A0 =10,A1 =4,A2 =2,A3 =A4 =0,thustheansweris10+4×2+2×3=24.
题意:
给出n,m,k,在n*m的网格内填[1,k]的整数,定义一个格子是great的,如果满足填在这个格子中的数是本行和本列中严格的最大值。定义A-g为网格中恰好有g个great格子的填法数,求Σ(g+1)A-g。
题解:
这题乍一看需要用组合数学 容斥原理计算A-g,但是这样做比较麻烦复杂。但其实这题是(g+1)的套路。。。简便做法是观察整体,把问题转化成每个位置是great格子对最终答案的贡献和,这样就绕开了A-g的计算。
首先,考虑整体的填法:K^(M×N)——这个是容易计算的,那么我们先企图用整体填法数化简待求式!我们发现将待求式展开,后面的ΣA-g的和便是整体的填法数。(一般都需要先拿整体化简一把!)
于是现在只需着手计算Σg*A-g,这个就用贡献和的思想转化,因为有g个great格的填法数乘了个g相当于摊到了这g个位置上,也就是说每个great格独立了,也即每一个格是great格对Σg*A-g贡献=使这个格是great的所有填法总数:
Contrib=Σ(i=1到i=K-1)i^(N-1+M-1)×K^[(N-1)×(M-1)] (转化为贡献和,有点智力题的感觉orz..)
这里注意一点:以上公式没有考虑n=m=1的情况,因为这时填1也算是great格(而以上公式从填2开始考虑的)
从而最后
ans=Contrib×N×M+K^(M×N)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int inf=0x3fffffff;
const ll mod=1000000007;
const int maxn=20+10;
ll fpow(int p,int x)
{
ll ans=1,t=p;
while(x)
{
if(x&1) ans=(ans*t)%mod;
t=(t*t)%mod;
x/=2;
}
return ans;
}
int main()
{
int cas;
scanf("%d",&cas);
rep(kase,1,cas+1)
{
ll ans=0;
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
rep(i,1,k)
{
ll res=fpow(i,n-1+m-1);
ans=(ans+res)%mod;
}
ans=(ans*fpow(k,(n-1)*(m-1)))%mod;
ans=ans*n%mod*m%mod;
ans=(ans+fpow(k,n*m))%mod;
if(n==1&&m==1) ans=(ans+1)%mod;
printf("Case #%d: %I64d\n",kase,ans);
}
return 0;
}