Gym - 101194H Great Cells

题目链接:https://codeforces.com/gym/101194/attachments

Problem H. Great Cells

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 } 

 如果有错误请评论指出

猜你喜欢

转载自www.cnblogs.com/meanttobe/p/11626130.html
今日推荐