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
*/

  

posted @ 2020-08-06 19:40  wqtnb_tql_qwq_%%%  阅读(133)  评论(0编辑  收藏  举报