Gym101194 H Great Cells
阿新 • • 發佈:2018-11-25
一堆人做出來了,就我不會做,感覺我完全不會計數題啊,菜的雅痞。還好最後qt想出來了,不然要涼。
看似值域為1-k,然後求恰好有g個greatcell很像多校裡面jls的一道題,然而這個限制更多,對於一個g已經這麼難求了,而對於所有g我感覺簡直冇得任何辦FA。
於是繼上次遇到那個輸出X^3次方的套路後,這題的套路又在他要輸出的答案上,對 (g+1)Ag 求和拆成2個部分,sigma Ag就是所有的方案數了,因為一個任意放的方案數對對應形成一個Ag的一個方案,所有的放法就是k^nm
然後就是sigma (g*Ag)這個轉換是真的關鍵,對於一種形成Ag的方案,要乘上一個g,也就是這個方案裡面的g個greatcells計了一遍數,那麼我們從另外一個角度考慮,對於一個格子,如果他是greatcell,對於他是greatcell的所有方案數,他都要計一次數,那麼就問題變成了有多少方案中,這個格子要計數,這樣就簡單很多了,假設他放的是i,那麼n-1+m-1個格子智慧放1到i-1,而其餘的(n-1)*(m-1)個格子還是1-k隨便放的,那麼這個格子放顏色i時候的貢獻就是(i-1)^(n-1+m-1)*k^((n-1)*(m-1)),而對於n*m個格子,這個貢獻都是一樣的,那麼直接乘就好
#include<bits/stdc++.h> #define maxl 201 #define mod 1000000007 int n,m,k,cas; long long ans; inline void prework() { scanf("%d%d%d",&n,&m,&k); } inline long long qp(long long a,long long b) { long long ans=1,cnt=a; while(b) { if(b&1) ans=(ans*cnt)%mod; cnt=(cnt*cnt)%mod; b>>=1; } return ans; } inline void mainwork() { ans=qp(k,n*m); long long tmp=0; for(int i=1;i<=k;i++) tmp=(tmp+qp(i-1,n-1+m-1))%mod; tmp=tmp*qp(k,(n-1)*(m-1))%mod; ans=(ans+tmp*n%mod*m%mod)%mod; } long long print() { printf("Case #%d: %lld\n",cas,ans); } int main() { int t; scanf("%d",&t); for(cas=1;cas<=t;cas++) { prework(); mainwork(); print(); } return 0; }