topic
analysis:
The old rules, expected to be ready to meet at any time to surrender. . .
Generally thought of by-bit processing, and then were down search, then the number of combinations of simple calculations it. . .
But the communication between the two sides of the block count how even expect it?
Well, to surrender. . .
Under term problem solution. . .
Sure enough, the search is credited. .
First we let F (n, m) denotes the n points takes a value [0, 2 ^ m) is the sum of all minimum spanning tree Consideration
Then Ans = F (n, m) / 2 ^ (n * m)
Then set G (S, T, m) represents a portion of the point set of size S, size another portion is T, the value of the point right after between [0, 2 ^ m), where all the sum of the weights minimum edge
So F (n, m) can be found in mind:
F(n,m)=
Sigma (I =. 1 ... n-) C (n-, I) (which point is selected) * (
F. (I,. 1-m) * 2 ^ ((Ni) * (. 1-m)) (part of the search program down then multiplier) +
F. (Ni,. 1-m) * 2 ^ (I * (. 1-m)) (the other part) +
G (I, Ni,. 1-m) (intermediate communication side) +
^ 2 (. 1-m) * 2 ^ (n-* (. 1-m)) (Consideration must spend multiplied by the number of programs) )
Then we come to find G:
Cheese we provided a number of function P (S, T, m, K) represents a set of points S, T, value [0, when 2 ^ m), the right edge is greater than a minimum value of equal to K
G (S, T, m) can be subtly into sigma (i = 1 ... (2 ^ m-1)) P (S, T, m, i)
Heavy secret, the brain can fill it, and about the same feeling with the prefix
Then P is very good demand, and violently S and T will continue to go down by 01 divided, into the statistics a bit when all the answers are not divided
Search triple in mind, but also so difficult equation
Immortal title Orz
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #define maxn 55 #define maxm 9 #define MOD 258280327 using namespace std; inline long long getint() { long long num=0,flag=1;char c; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9')num=num*10+c-48,c=getchar(); return num*flag; } int n,m; long long C[maxn][maxn],F[maxn][maxm],G[maxn][maxn][maxm],P[maxn][maxn][maxm][1<<maxm],pw[maxn*maxm]; inline long long ksm(long long num,long long k) { long long ret=1; for(;k;k>>=1,num=num*num%MOD)if(k&1)ret=ret*num%MOD; return ret; } inline long long getP(int S,int T,int M,int K) { if(S>T)swap(S,T); if(!S||K<=0)return pw[(S+T)*M]; if(K>=(1<<M))return 0; if(~P[S][T][M][K])return P[S][T][M][K]; long long tmp=0; for(int i=0;i<=S;i++)for(int j=0;j<=T;j++) if((i==0&&j==T)||(i==S&&j==0))tmp=(tmp+getP(S,T,M-1,K-(1<<(M-1))))%MOD; else tmp=(tmp+getP(i,j,M-1,K)*getP(S-i,T-j,M-1,K)%MOD*C[S][i]%MOD*C[T][j]%MOD)%MOD; return P[S][T][M][K]=tmp; } inline long long getG(int S,int T,int M) { if(!M)return 0; if(S>T)swap(S,T); if(~G[S][T][M])return G[S][T][M]; long long tmp=0; for(int i=1;i<(1<<M);i++) tmp=(tmp+getP(S,T,M,i))%MOD; return G[S][T][M]=tmp; } inline long long getF(int N,int M) { if(!M||N<2)return 0; if(~F[N][M])return F[N][M]; long long tmp=2*getF(N,M-1)%MOD; for(int i=1;i<N;i++) tmp=(tmp+C[N][i]*(getF(i,M-1)*pw[(N-i)*(M-1)]%MOD+getF(N-i,M-1)*pw[i*(M-1)]%MOD+getG(i,N-i,M-1)+(1<<(M-1))*pw[N*(M-1)]%MOD))%MOD; return F[N][M]=tmp; } int main() { n=getint(),m=getint(); pw[0]=1;for(int i=1;i<=n*m;i++)pw[i]=pw[i-1]*2%MOD; for(int i=0;i<=n;i++) { C[i][0]=C[i][i]=1; for(int j=1;j<i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD; } memset(F,-1,sizeof F),memset(G,-1,sizeof G),memset(P,-1,sizeof P); printf("%lld\n",getF(n,m)*ksm(pw[n*m],MOD-2)%MOD); }