1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| #include <bits/stdc++.h> #define STC static #define fi first #define se second using LL = long long; const int N = 2e5 + 100, P = 998244353; int n, pr[N], ct = 0, mp[N], num[N], ans; struct Edge{ int to, x, y; }; std::vector<Edge> G[N]; std::map<int, int> ha, as; int gcd(int a, int b){ return b ? gcd(b, a % b) : a; } void prev() { STC std::bitset<N> vis; memset(mp, 0x3f, sizeof mp); vis[1] = 1; for (int i = 2; i < N; ++i) { if (!vis[i]){ pr[++ct] = i, mp[i] = i; } for (int j = 1, t; j <= ct && LL(pr[j]) * i < N; ++j) { mp[pr[j] * i] = std::min(mp[pr[j]], mp[i]), vis[pr[j] * i] = 1; if (i % pr[j] == 0) break; } } } int qpow(int x, int y) { int res = 1; for (; y; y >>= 1, x = LL(x) * x % P) if (y & 1) res = LL(res) * x % P; return res; } int get_ans() { int res = 1; for (auto i : as) res = LL(res) * qpow(i.fi, i.se) % P; return res; } bool chkmin(int &x, int &y){ return x > y ? x = y, 1 : 0; } void dfs(int x, int fa, int now) { for (auto e : G[x]) if (e.to != fa) { num[e.to] = LL(now) * qpow(e.x, P - 2) % P * e.y % P; int t = e.x; for (int cnt, tp; t != 1; ) { cnt = 0, tp = mp[t]; while (t % tp == 0) ++cnt, t /= tp; chkmin(as[tp], ha[tp] -= cnt); } t = e.y; for (int cnt, tp; t != 1; ) { cnt = 0, tp = mp[t]; while (t % tp == 0) ++cnt, t /= tp; ha[tp] += cnt; } dfs(e.to, x, num[e.to]); t = e.x; for (int cnt, tp; t != 1; ) { cnt = 0, tp = mp[t]; while (t % tp == 0) ++cnt, t /= tp; ha[tp] += cnt; } t = e.y; for (int cnt, tp; t != 1; ) { cnt = 0, tp = mp[t]; while (t % tp == 0) ++cnt, t /= tp; ha[tp] -= cnt; } } } int main() { int T; for (prev(), scanf("%d", &T); T--; ) { scanf("%d", &n), ans = 0; for (int i = 1; i <= n; ++i) G[i].clear(); ha.clear(), as.clear(); for (int i = 1, a, b, c, d, t; i < n; ++i) { scanf("%d %d %d %d", &a, &b, &c, &d), t = gcd(c, d); c /= t, d /= t; G[a].push_back({b, c, d}), G[b].push_back({a, d, c}); for (int cnt, tp; c != 1; ) { cnt = 0, tp = mp[c]; while (c % tp == 0) ++cnt, c /= tp; ha[tp] += cnt; } for (int cnt, tp; d != 1; ) { cnt = 0, tp = mp[d]; while (d % tp == 0) ++cnt, d /= tp; ha[tp] += cnt; } } as = ha; dfs(1, -1, num[1] = get_ans()); int iv = qpow(get_ans(), P - 2); for (int i = 1; i <= n; ++i) num[i] = LL(iv) * num[i] % P; for (int i = 1; i <= n; ++i) ans = (ans + num[i]) % P; printf("%d\n", ans); } return 0; }
|