CF 111D Petya and Coloring(組合計數)
阿新 • • 發佈:2019-01-07
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<set> #include<string> #include<queue> #define inf 1600005 #define M 40 #define N 100001 #define maxn 300005 #define eps 1e-12 #define zero(a) fabs(a)<eps #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define pb(a) push_back(a) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define LL unsigned long long #define MOD 1000000007 #define lson step<<1 #define rson step<<1|1 #define sqr(a) ((a)*(a)) #define Key_value ch[ch[root][1]][0] #define test puts("OK"); #define pi acos(-1.0) #define lowbit(x) ((-(x))&(x)) #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; int n,m,k; LL fac[1000005]={1},rev[1000005]={1}; LL dp[1005]; LL PowMod(LL a,LL b){ LL ret=1; while(b){ if(b&1) ret=ret*a%MOD; a=a*a%MOD; b>>=1; } return ret; } void Init(){ for(int i=1;i<=1000000;i++) fac[i]=fac[i-1]*i%MOD,rev[i]=PowMod(fac[i],MOD-2); } LL C(int n,int m){ return (fac[n]*rev[m]%MOD)*rev[n-m]%MOD; } int main(){ //freopen("in.txt","r",stdin); Init(); while(scanf("%d%d%d",&n,&m,&k)!=EOF){ if(m==1) {printf("%I64d\n",PowMod(k,n));continue;} for(int i=1;i<=n&&i<=k;i++){ dp[i]=PowMod(i,n); for(int j=1;j<i;j++){ dp[i]=(dp[i]-C(i,j)*dp[j]%MOD+MOD)%MOD; } } LL ret=0; if(m==2){ for(int i=1;i<=n&&i<=k;i++){ LL tmp=(dp[i]*dp[i])%MOD; tmp=(tmp*C(k,i)%MOD)*C(k,i)%MOD; ret=(ret+tmp)%MOD; } } else{ for(int i=1;i<=n&&i<=k;i++){ for(int j=0;j<=n&&j<=k;j++){ if(k<2*j+i||i+j>n) break; LL tmp=dp[i+j]*dp[i+j]%MOD; tmp=((tmp*C(k,i)%MOD)*C(k-i,j)%MOD)*C(k-i-j,j)%MOD; tmp=(tmp*PowMod(i,n*(m-2)))%MOD; ret=(ret+tmp)%MOD; } } } printf("%I64d\n",ret); } return 0; }