比赛 CSP2023-S模拟赛 评测结果 AAAAAAAAAA
题目名称 编辑题目 最终得分 100
用户昵称 zxhhh 运行时间 2.842 s
代码语言 C++ 内存使用 131.62 MiB
提交时间 2023-10-17 19:57:04
显示代码纯文本
#include <bits/stdc++.h>
#define lowbit(def_x) def_x&-def_x

using namespace std;
const int N = 1e6+5, mod = 998244353; 
typedef long long ll;
ll qpow (ll x, ll y) {
    ll res = 1;
    while (y) {
        if (y&1) res = res*x%mod; 
        x = x*x%mod; y >>= 1; 
    }
    return res;
}
int n, m, hd[N], ver[N<<1], nxt[N<<1], w[N<<1], idx = 1, t[N], d[N], df2[N], c[N], dft, r[N], st[N<<1];
int dfn[N], dfs_t, low[N], dcc_cnt, dcc_idx[N], stk[N], ed, siz[N], op[N<<1];
inline void add (int x, int k) {
    while (x <= n) c[x] += k, x += lowbit(x); 
}
inline int query (int x) {
    int res = 0; while (x) res += c[x], x -= lowbit(x); return res;
}
vector <int> dcc[N], g[N];  
inline void add (int x, int y, int v) {
    w[++idx] = v; 
    ver[idx] = y; st[idx] = x;
    nxt[idx] = hd[x]; 
    hd[x] = idx;
}
inline int read () {
    int num = 0; char ch = getchar(); 
    while (ch < '0' || ch > '9') ch = getchar(); 
    while (ch >= '0' && ch <= '9') num = (num<<1)+(num<<3)+(ch^48), ch = getchar(); 
    return num; 
}

void tarjan (int p, int eid) {
    dfn[p] = low[p] = ++dfs_t; stk[++ed] = p;
    for (int i = hd[p];i;i = nxt[i]) {
        if (i == eid) continue; 
        int y = ver[i]; 
        if (dfn[y]) low[p] = min(low[p], dfn[y]); 
        else tarjan(y, i^1), low[p] = min(low[p], low[y]); 
    }
    if (dfn[p] == low[p]) {
        op[eid] = op[eid^1] = 1; 
        ++dcc_cnt; 
        int x; 
        do {
            x = stk[ed--]; 
            dcc_idx[x] = dcc_cnt; 
            dcc[dcc_cnt].push_back(x); 
//            cout << dcc_cnt << " " << x << endl; 
        } while (x != p); 
    }
}

void dfs (int p) {
    df2[p] = ++dft; siz[p] = dcc[p].size(); 
    for (auto i : dcc[p]) {
        for (int j = hd[i];j;j = nxt[j]) {
            int y = ver[j]; 
            if (dcc_idx[y] == p || df2[dcc_idx[y]]) continue; 
            d[dcc_idx[y]] = d[p]+1;
            dfs(dcc_idx[y]); siz[p] += siz[dcc_idx[y]]; 
        }
    }
    r[p] = dft; 
}

int main () {
    freopen("edit.in", "r", stdin); 
    freopen("edit.out", "w", stdout); 
    // Genshin start 
    n = read(); m = read(); 
    for (int i = 1;i <= m;i++) {
        int x = read(), y = read(), v = read(); 
        t[i] = v; 
        add(x, y, v); add(y, x, v); 
    }    
    sort(t+1, t+1+m); int tl = unique(t+1, t+1+m)-t-1; 
    for (int i = 2;i <= idx;i++) w[i] = lower_bound(t+1, t+1+tl, w[i])-t; 
    tarjan(1, 0); d[1] = 1; 
    dfs(1); 
    for (int i = 2;i <= idx;i += 2) {
        int x = dcc_idx[st[i]], y = dcc_idx[ver[i]]; 
        if (d[x] < d[y]) swap(st[i], ver[i]);  
        g[w[i]].push_back(i); 
    }
    int ans = 0;
    for (int i = 1;i <= m;i++) {
        if (g[i].size() <= 1) continue; 
        for (auto j : g[i]) add(df2[dcc_idx[ver[j]]], 1);
        for (auto j : g[i]) {
            if (!op[j]) ans += n, ans %= mod; 
            else {
                int x = dcc_idx[st[j]]; 
                int y = query(r[x])-query(df2[x]-1); 
                if (y) ans += siz[x]; 
                if (y+1 < g[i].size()) ans += n-siz[x]; 
                ans %= mod;
            }
        }
        for (auto j : g[i]) add(df2[dcc_idx[ver[j]]], -1); 
    }
    printf("%lld\n", qpow((ll)n*m%mod, mod-2)*ans%mod); 
    return 0;
}