• Codeforces #430 Div2 C


    #430 Div2 C

    题意

    给出一棵带点权的树,每一个节点的答案为从当前节点到根节点路径上所有节点权值的最大公因子(在求最大共因子的时候可以选择把这条路径上的任意一点的权值置为0)。对于每一个节点单独考虑,输出最大的答案。

    分析

    本以为是一道树形DP,写完就 WA 了。
    补题的时候呢时间复杂度很迷,写完就 T 了。
    一直想着这道题可以抢救一下,还好没看题解,其实只要想想 gcd 的下降速度是很快的,然后就可以乱搞了。

    在搜索的时候记录下前面是否把某个权值当做0来算了,分情况讨论下即可。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 2e5 + 100;
    struct Edge {
        int to, nxt;
    }e[MAXN << 1];
    int head[MAXN], cnt = 0;
    void add(int u, int v) {
        e[cnt].to = v;
        e[cnt].nxt = head[u];
        head[u] = cnt++;
    }
    int a[MAXN], dp[MAXN];
    
    int gcd(int a, int b) {
        return !b ? a : gcd(b, a % b);
    }
    
    void dfs(int fa, int u, int fac, int is) {
        if(fac == 1) return;
        dp[u] = max(dp[u], fac);
        for(int i = head[u]; ~i; i = e[i].nxt) {
            int v = e[i].to;
            if(v != fa) {
                int gcd_ = gcd(fac, a[v]);
                if(is && gcd_ > 1) {
                    dfs(u, v, gcd_, 1);
                } else if(!is) {
                    if(gcd_ < fac) {
                        if(gcd_ > 1) dfs(u, v, gcd_, 0); // 看似很暴力,但是注意到 gcd 的下降速度是很快的,且保证了 gcd_ < fac 。
                        dfs(u, v, fac, 1);
                    }
                    else dfs(u, v, fac, 0);
                }
            }
        }
    }
    //适用于正整数
    template <class T>
    inline void scan_d(T &ret) {
        char c; ret=0;
        while((c=getchar())<'0'||c>'9');
        while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
    }
    int main() {
        memset(head, -1, sizeof head);
        int n;
        scan_d(n);
        for(int i = 1; i <= n; i++) {
            scan_d(a[i]);
            dp[i] = 1;
        }
        for(int i = 1; i < n; i++) {
            int u, v;
            scan_d(u); scan_d(v);
            add(u, v);
            add(v, u);
        }
        dfs(0, 1, 0, 1);
        dfs(0, 1, a[1], 0);
        for(int i = 1; i <= n; i++) {
            printf("%d%c", dp[i], " 
    "[i == n]);
        }
        return 0;
    }
    
  • 相关阅读:
    poj 2021
    树状数组的修改+查询
    poj 1182
    windows网络模型之重叠IO(完成例程)的使用
    windows网络模型之重叠IO的使用
    python解析HTML之:PyQuery库的介绍与使用
    windows 网络通讯模型Overlapped (转)(未看)
    (转)写的非常好的一篇HTTP协议详解
    (转)Wireshark基本介绍和学习TCP三次握手
    http中COOKIE和SESSION有什么区别?(转知乎)
  • 原文地址:https://www.cnblogs.com/ftae/p/7454843.html
Copyright © 2020-2023  润新知