hdu_6836 Expectation
生成树计数
按位枚举每一位为1的个数在进行最小生成树计数时间复杂度O(Tn^2*30)
#include <bits/stdc++.h> using namespace std; #define N 110 #define LL long long #define ll long long LL K[N][N],a[N][N][31]; const ll mod=998244353; LL gauss(int n){ LL res=1; for(int i=1;i<=n-1;i++){ for(int j=i+1;j<=n-1;j++){ while(K[j][i]){ int t=K[i][i]/K[j][i]; for(int k=i;k<=n-1;k++) K[i][k]=(K[i][k]-t*K[j][k]+mod)%mod; swap(K[i],K[j]); res=-res; } } res=(res*K[i][i])%mod; } return (res+mod)%mod; } ll qpow(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=ans*x%mod; x=x*x%mod; y/=2; } return ans; } int main(){ int n,m,t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); ll ans=0; int kmax=0; memset(K,0,sizeof(K)); memset(a,0,sizeof(a)); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); K[u][u]++; K[v][v]++; K[u][v]--; K[v][u]--; int k=0; while(w){ if(w&1)a[u][v][k]++,a[v][u][k]++; w/=2; k++; } kmax=max(k,kmax); } ll x=gauss(n); if(x==0){puts("0"); continue;} for(int k=0;k<=kmax;k++){ memset(K,0,sizeof(K)); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(a[i][j][k]){ K[i][i]+=a[i][j][k]; K[j][j]+=a[i][j][k]; K[i][j]-=a[i][j][k]; K[j][i]-=a[i][j][k]; } ans+=gauss(n)*(1<<k); ans%=mod; } printf("%lld\n",ans*qpow(x,mod-2)%mod); } return 0; } /* 1 3 2 1 2 2 2 3 2 */