比赛 |
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;
}