• hdu 6836


    hdu 6836

    题解:

    给你一张图求所有生成树的&的期望。

    题解:

    由于求的是 & 那么可以考虑 枚举二进制

    如果答案的二进制中第 i 位 为1, 那么所选的边 所有权值的第i位都为1

    所有可以把答案拆成 二进制的和

    那么就可枚举每个二进制。

    将第i为二进制为1的边组成的生成树设为 (cnti)

    总共的生成树为 (total) 那么期望就是 (cnti* 2^i / total (0 le i le29))

    这里求生成树的个数要用的一个算法就是 生成树计数

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 107;
    
    #define LL long long
    
    const LL MOD = 998244353;
    const LL mod = 998244353;
    
    
    
    LL K[N][N];
    LL gauss(int n){//求矩阵K的n-1阶顺序主子式
        LL res=1;
        for(int i=1;i<=n-1;i++){//枚举主对角线上第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]);//交换i、j两行
                    res=-res;//取负
                }
            }
            res=(res*K[i][i])%MOD;
        }
        return (res+MOD)%MOD;
    }
    
    struct edge{
        int u, v, w;
    }e[10007];
    
    LL ksm(LL a, LL b) {
        LL base = 1;
        while (b) {
            if (b & 1) {
                base = (base * a) % mod;
            }
            b = b / 2;
            a = a * a % mod;
        }
        return base % mod;
    }
    
    int main(){
    
        int t, n, m;
        scanf("%d", &t);
        while (t--) {
            memset(K, 0, sizeof(K));
            scanf("%d %d", &n, &m);
            for (int i = 1; i <= m; i++) {
                int u, v, w;
                scanf("%d %d %d", &u, &v, &w);
                e[i] = {u, v, w};
                K[u][u]++;
                K[v][v]++;
                K[u][v]--;
                K[v][u]--;
            }
            LL total = gauss(n);
            LL ans = 0;
            LL inv = ksm(total, mod - 2);
            for (int i = 0; i < 30; i++) {
                memset(K, 0, sizeof(K));
                for (int j = 1; j <= m; j++) {
                    if (((1 << i) & e[j].w)) {
                        K[e[j].u][e[j].u]++;
                        K[e[j].v][e[j].v]++;
                        K[e[j].u][e[j].v]--;
                        K[e[j].v][e[j].u]--;
                    }
                }
                LL cnt = (1 << i);
                LL cat = gauss(n);
    
                cnt = (cnt % mod * cat % mod) % mod;
                ans = (ans + cnt) % mod;
            }
            ans = (ans % mod * inv % mod) % mod;
            printf("%lld
    ", ans);
        }
    }
    
  • 相关阅读:
    吉他音阶笔记(以C调为基准)
    小程序页面跳转问题
    Adobe-premierej剪辑视频分辨率问题及格式转换画面质量分辨率
    关于ps抠图问题,制作公章,公章的复制
    premiere视频剪辑关于导出视屏分辨率的问题
    最后一个单词的长度
    10.两个链表的交叉
    软件工程——个人总结
    软件工程——团队专业4
    软件工程——团队答辩
  • 原文地址:https://www.cnblogs.com/BOZHAO/p/13450052.html
Copyright © 2020-2023  润新知