标签:stdout inline fpm mem 集合 git type pen 枚举
#include <bits/stdc++.h>
typedef long long LL;
inline int read(int Num = 0, int Flag = 1)
{
    char ch = getchar();
    for (; !isdigit(ch); ch = getchar()) 
        if (ch == ‘-‘)
            Flag = -1;
    for (;  isdigit(ch); ch = getchar())
        Num = Num * 10 + ch - ‘0‘;
    return Num *= Flag;
}
template <typename T> bool chkmax(T &a, T b) { return a < b? a = b, true : false; }
template <typename T> bool chkmin(T &a, T b) { return a > b? a = b, true : false; }
const int MAXN = 50 + 5;
const int mod = 998244353;
const int base = 1e4;
int fpm(int x, int e)
{
    int ret = 1;
    for (; e; e >>= 1) {
        if (e & 1) 
            ret = (LL)ret * x % mod;
        x = (LL)x * x % mod;
    }
    return ret;
}
int N, M, mul_num;
std::vector<int> G[MAXN];
int from[MAXN], to[MAXN], p[MAXN];
int size, tot;
int id[MAXN], occur[MAXN];
void DFS_work(int u, int tot)
{
    id[u] = size ++;
    occur[u] = tot;
    for (int i = 0; i < (int)G[u].size(); ++i) {
        int v = G[u][i];
        if (id[v] < 0) DFS_work(v, tot);
    }
}
int sum[MAXN][MAXN];
int dp[MAXN][MAXN];
int main()
{
    freopen("random.in", "r", stdin);
    freopen("random.out", "w", stdout);
    N = read(), M = read();
    mul_num = fpm(base, N * (N-1));
    for (int i = 1; i <= M; ++i) {
        int u = read(), v = read(), w = read();
        G[u].push_back(v);
        G[v].push_back(u);
        from[i] = u, to[i] = v;
        p[i] = (LL)w * fpm(base, mod - 2) % mod;
    }
    int allblock_size = 0;
    memset(id, -1, sizeof id);
    for (int i = 1; i <= N; ++i) {
        if (id[i] >= 0) continue;
        size = 0;
        tot ++;
        DFS_work(i, tot);
        allblock_size += size;
        for (int s = 0; s < 1<<size; ++s) {
            int coe = 1;
            for (int j = 1; j <= M; ++j) {
                if (occur[from[j]] == tot && (((s >> id[from[j]]) ^ (s >> id[to[j]])) & 1)) {
                    coe = coe * 2 % mod;
                    coe = (LL)coe * ((s >> id[from[j]]) & 1? p[j] : mod + 1 - p[j]) % mod;
                }
            }
            int bit = __builtin_popcount(s);
            sum[tot][bit] = (sum[tot][bit] + coe) % mod;
        }
    }
    dp[0][0] = 1;
    for (int i = 0; i < tot; ++i) {
        for (int j = 0; j <= N; ++j) {
            for (int k = 0; k + j <= N; ++k)
                dp[i+1][j+k] = (dp[i+1][j+k] + (LL)dp[i][j] * sum[i + 1][k] % mod) % mod;
        }
    }
    int ans = 0;
    assert(allblock_size == N);
    for (int i = 1; i <= N; ++i) {
        ans = (ans + (LL)dp[tot][i] * fpm((mod + 1) / 2, i * (N-i)) % mod) % mod;
    }
    printf("%lld\n", (LL)ans * mul_num % mod);
    return 0;
}
标签:stdout inline fpm mem 集合 git type pen 枚举
原文地址:https://www.cnblogs.com/pbvrvnq/p/8763202.html