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
| #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10, mod = 998244353; int inv[N]; int cnt, p[N], f[N]; int n, tot, ans[N], cur[N]; struct Edge { int v, p, q; }; vector<Edge> g[N]; void add(int x, int k) { for (; x > 1; x /= f[x]) cur[f[x]] += k, ans[f[x]] = min(ans[f[x]], cur[f[x]]); } void dfs(int x, int fa, int s) { (tot += s) %= mod; for (Edge i : g[x]) if (i.v != fa) { add(i.p, -1), add(i.q, 1); dfs(i.v, x, (LL)s * i.q % mod * inv[i.p] % mod); add(i.p, 1), add(i.q, -1); } } void init() { inv[1] = 1; for (int i = 2; i < N; i++) inv[i] = -(LL)(mod / i) * inv[mod % i] % mod; for (int i = 2; i < N; i++) { if (!f[i]) p[++cnt] = f[i] = i; for (int j = 1; j <= cnt && i * p[j] < N; j++) { f[i * p[j]] = p[j]; if (i % p[j] == 0) break; } } } int binpow(int b, int k) { int res = 1; while (k) { (k & 1) && (res = (LL)res * b % mod); b = (LL)b * b % mod; k >>= 1; } return res; } int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() { init(); int T; cin >> T; while (T--) { cin >> n; tot = 0; for (int i = 1; i <= n; i++) g[i].clear(); for (int i = 1; i <= n; i++) cur[i] = 0; int st = 1; for (int i = 1, a, b, c, d; i < n; i++) { cin >> a >> b >> c >> d; int e = gcd(c, d); c /= e, d /= e; g[a].push_back((Edge){b, c, d}); g[b].push_back((Edge){a, d, c}); add(c, 1), add(d, 1); st = (LL)st * c % mod * d % mod; } for (int i = 1; i <= n; i++) ans[i] = cur[i]; dfs(1, 0, st); for (int i = 1; i <= n; i++) for (int j = 1; j <= ans[i]; j++) tot = (LL)tot * inv[i] % mod; cout << (tot + mod) % mod << endl; } return 0; }
|