Gym - 101194H Great Cells
Problem H. Great Cells
题目链接:https://codeforces.com/gym/101194/attachments
Input file: Standard Input
Output file: Standard Ouptut
Time limit: 2 seconds
题目大意:
在N×M的网格里填[1,K]的整数,如果满足这个格子中的数是本行和本列中严格的最大值,定义这个格子是great的。定义A-g为网格中恰好有g个great格子的填法数,求Σ(g+1)A-g(mod1e9+7). 0<=g<=N*M
解题思路:
将式子分为两部分,一部分是Σ(A-g),另一部分是Σ(g*A-g).前一部分是指有0个great到n*m个great的之和。也就是在网格中任意填的所有情况,即K^(n*m)。而后一部份是指有g个great时,累加上g个great的所有放法并乘上g。其实可以认为,认为放法为num,num=(1+1+1+1+....),g*num=g*(1+1+1+1...)=g+g+g+g+g+......。每一种放法将会放g个,所以只要当这一格是great时那么,这一格就加1。最后将每个方格的数加起来,当然这样不可行,不过分析后可以知道每个格的数值其实就是它是great的所有情况总和。而如果这个格是great,那么同行同列的小格就一定小于它放的数值,而其他的可以任意填。所以枚举其中一个格放的数值即可。即Σ( ksm(i,n-1+m-1) * ksm( k,(n-1)*(m-1) ) ).1<=i<k。所以其后半部分总和就是n*m*Σ( ksm(i,n-1+m-1) * ksm( k,(n-1)*(m-1) ) ) 1<=i<k
代码:
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const ll mod=1000000007;
5 ll ksm(ll a,ll b){
6 ll sum=1;
7 while(b){
8 if(b&1)
9 sum=sum*a%mod;
10 a=a*a%mod;
11 b>>=1;
12 }
13 return sum;
14 }
15
16 int main(){
17 ll t,n,m,k;
18 ll ans,ans1,ans2=0,count=0;
19 cin>>t;
20 while(t--){
21 count++;
22 ans2=0;
23 cin>>n>>m>>k;
24 ans1=ksm(k,n*m);
25 for(ll i=1;i<k;i++){
26 ans2=(ans2+(ksm(i,n-1+m-1)*ksm(k,(m-1)*(n-1))%mod))%mod;
27 }
28 ans=(ans1+m*n*ans2%mod)%mod;
29 printf("Case #%lld: %lld\n",count,ans);
30 }
31 return 0;
32 }
如果有错误请评论指出