药水由n种成分组成,每种成分的质量为正整数,第i种成分的比例为r[i], r[1]+...+r[n]=1, 给定n-1种关系:i, j, x, y, i / j = x / y,求药水质量最小值

题目

思路:

药水由n种成分组成,每种成分的质量为正整数,第i种成分的比例为r[i], r[1]+...+r[n]=1, 给定n-1种关系:i, j, x, y, i / j = x / y,求药水质量最小值_第1张图片

#include 
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 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;
}

你可能感兴趣的:(codeforces,算法)