zoukankan      html  css  js  c++  java
  • HDU6430 Problem E. TeaTree【dsu on tree】

    Problem E. TeaTree

    Problem Description
    Recently, TeaTree acquire new knoledge gcd (Greatest Common Divisor), now she want to test you.
    As we know, TeaTree is a tree and her root is node 1, she have n nodes and n-1 edge, for each node i, it has it’s value v[i].
    For every two nodes i and j (i is not equal to j), they will tell their Lowest Common Ancestors (LCA) a number : gcd(v[i],v[j]).
    For each node, you have to calculate the max number that it heard. some definition:
    In graph theory and computer science, the lowest common ancestor (LCA) of two nodes u and v in a tree is the lowest (deepest) node that has both u and v as descendants, where we define each node to be a descendant of itself.

    给出一棵以(1)为根的树,每个点有权值(w[i]),两个不同的点(u,v)可以使他们的(lca)得到一个大小为(gcd(w[u],w[v]))值,现在问每个点所能得到的最大值

    可以考虑枚举每个(lca),然后任意两个不同的子树中的两个值取(gcd),这样是(n^2)
    考虑启发式合并,用一个数组来记录所有出现过的因子,假设当前处理到点(u),现在已经处理出了一些(u)的子树中的所有因子了,现在到(v)的子树,那就可以先对(v)为根的子树中的所有点找出最大出现过的因子,然后再把子树里的所有点的因子加入进去,这样可以防止处理到相同子树中的点

    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 1e5+7;
    int n,w[MAXN],sz[MAXN],son[MAXN],ret[MAXN],res,app[MAXN],st[MAXN],ed[MAXN],id[MAXN],num;
    vector<int> d[MAXN],G[MAXN];
    void preprocess(){
        for(int i = 1; i < MAXN; i++) for(int j = i; j < MAXN; j+=i) d[j].emplace_back(i);
    	for(int i = 1; i < MAXN; i++) reverse(d[i].begin(),d[i].end());
    }
    void dfs(int u){
        sz[u] = 1; st[u] = ++num; id[num] = u;
        for(int v : G[u]){
            dfs(v);
            sz[u] += sz[v];
            if(sz[v]>sz[son[u]]) son[u] = v;
        }
        ed[u] = num;
    }
    void update(int val, int inc){ for(int x : d[val]) app[x] += inc; }
    int query(int val){ for(int x : d[val]) if(app[x]) return x; return -1; }
    void search(int u, bool clear){
        for(int v : G[u]) if(v!=son[u]) search(v,true);
        if(son[u]) search(son[u],false);
        res = -1;
        for(int v : G[u]) if(v!=son[u]) {
            for(int i = st[v]; i <= ed[v]; i++) res = max(res,query(w[id[i]]));
            for(int i = st[v]; i <= ed[v]; i++) update(w[id[i]],1);
        }
        res = max(res,query(w[u]));
        update(w[u],1);
        ret[u] = res;
        if(clear) for(int i = st[u]; i <= ed[u]; i++) update(w[id[i]],-1);
    }
    void solve(){
        scanf("%d",&n);
        for(int i = 2; i <= n; i++){
            int par; scanf("%d",&par);
            G[par].emplace_back(i);
        }
        for(int i = 1; i <= n; i++) scanf("%d",&w[i]);
        dfs(1);
        search(1,false);
        for(int i = 1; i <= n; i++) printf("%d
    ",ret[i]);
    }
    int main(){
        preprocess();
        solve();
        return 0;
    }
    
  • 相关阅读:
     selenium webdriver test
    V8 初次接触(Qt5) 1+1=2 博客频道 CSDN.NET
    C++11 FAQ中文版
    做技术的,因为年龄和颈椎问题,想逐渐脱离码农状态,大家对3035岁职业规划有什么好的建议? 知乎
    一些idea
    如何来区分是我写的还是我转载的,
    firecurl
    python为什么叫好不叫座
    QTextCodec中的setCodecForTr等终于消失了 (Qt5) 1+1=2 博客频道 CSDN.NET
    Charles Web Debugging Proxy • HTTP Monitor / HTTP Proxy / HTTPS & SSL Proxy / Reverse Proxy
  • 原文地址:https://www.cnblogs.com/kikokiko/p/12776384.html
Copyright © 2011-2022 走看看