思路:


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
const int maxn = 1e6 + 5, inf = 1e9 + 5, maxm = 5e3 + 5, mod = 998244353, N = 1e6;;
int a[maxn];
int n, m;
string s;
int d[maxn];
struct Node{
int x, y, v;
};
struct Data{
int a, b;
}dat[maxn];
vector<Node> G[maxn];
int res = 0;
int c[maxn], minc[maxn], minp[maxn];
void init(){
minp[1] = 0;
for(int i = 2; i <= N; i++){
if(!minp[i]){
for(int j = i; j <= N; j += i){
minp[j] = i;
}
}
}
}
int qpow(int a, int b){
int res = 1;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void dfs(int u, int fa, int now){
res = (res + now) % mod;
for(auto z : G[u]){
int v = z.v, x = z.x, y = z.y;
if(v == fa) continue;
for(int i = x; i > 1; i /= minp[i]){
c[minp[i]]--;
minc[minp[i]] = min(minc[minp[i]], c[minp[i]]);//可以在分解x的时候取min,因为之前已经将x,y除以gcd,所以y的质数不会抵消x的质数
}
for(int i = y; i > 1; i /= minp[i]){
c[minp[i]]++;
}
dfs(v, u, now * qpow(x, mod - 2) % mod * y % mod);
for(int i = x; i > 1; i /= minp[i]){
c[minp[i]]++;
}
for(int i = y; i > 1; i /= minp[i]){
c[minp[i]]--;
}
}
}
void solve()
{
cin >> n;
res = 0;
for(int i = 1; i <= n; i++){
G[i].clear();
minc[i] = 0;
c[i] = 0;
}
for(int i = 1; i < n; i++){
int u, v, x, y;
cin >> u >> v >> x >> y;
int gcd = __gcd(x, y);
x /= gcd, y /= gcd;
// if(u > v) swap(u, v), swap(x, y);
G[u].pb({x, y, v});
G[v].pb({y, x, u});
}
dfs(1, 1, 1);
for(int i = 1; i <= n; i++){
if(minc[i]){
res = res * qpow(i, -minc[i]) % mod;
}
}
cout << res << '\n';
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
init();
// fac[0] = 1;
// for(int i = 1; i <= N; i++){
// fac[i] = fac[i - 1] * i % mod;
// }
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
该篇文章主要介绍了如何使用C++编程语言,结合质因数分解算法,解决与图论相关的问题,通过dfs遍历更新质数计数并计算最终结果。

被折叠的 条评论
为什么被折叠?



