zoukankan      html  css  js  c++  java
  • Codeforces 348B

    348B - Apple Tree

    我们设最后答案为 x , 我们我们就能用x表示出所有节点下面的苹果个数, 然后用叶子节点求lcm, 取最大的可行解。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    using namespace std;
    
    const int N = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, a[N];
    LL dv[N], sum[N], all;
    vector<int> leaf;
    vector<int> G[N];
    
    void solve(int u, int fa) {
        if(u != 1 && SZ(G[u]) == 1) leaf.push_back(u);
        sum[u] = a[u];
        for(int v : G[u]) {
            if(v == fa) continue;
            solve(v, u);
            sum[u] += sum[v];
        }
    }
    
    void dfs(int u, int fa) {
        if(dv[u] > all) {
            printf("%lld
    ", all);
            exit(0);
        }
        for(int v : G[u]) {
            if(v == fa) continue;
            if(u == 1) dv[v] = dv[u] * SZ(G[u]);
            else dv[v] = dv[u] * (SZ(G[u]) - 1);
            dfs(v, u);
        }
    }
    
    bool check(LL x) {
        for(auto& id : leaf) {
            if(x / dv[id] > a[id]) return false;
        }
        return true;
    }
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]), all += a[i];
        for(int i = 1; i < n; i++) {
            int u, v; scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dv[1] = 1;
        solve(1, 0);
        dfs(1, 0);
        LL lcm = 1;
        for(auto& id : leaf) {
            LL gcd = __gcd(lcm, dv[id]);
            if(1.0 * lcm / gcd * dv[id] > all) {
                printf("%lld
    ", all);
                return 0;
            }
            lcm = lcm / gcd * dv[id];
        }
        LL low = 1, high = all / lcm, ans = 0;
        while(low <= high) {
            LL mid = low + high >> 1;
            if(check(mid * lcm)) ans = mid, low = mid + 1;
            else high = mid - 1;
        }
        printf("%lld
    ", all - ans * lcm);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    话说 SVN 与 Git 之间的区别
    CentOS 7 之安装 Oracle 11gR2
    @meda媒体查询
    为样式找到应用目标-CSS选择器
    JQuery和原生JavaScript实现网页定位导航特效
    CSS代码缩写
    认识CSS样式
    文档类型、DOCTYPE切换和浏览器模式
    MIME 参考手册
    微格式(microformat)
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10351790.html
Copyright © 2011-2022 走看看