题目链接: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 }
如果有错误请评论指出
原文地址:https://www.cnblogs.com/meanttobe/p/11626130.html