zoukankan      html  css  js  c++  java
  • codeforces 842C. Ilya And The Tree(dfs,dp)

    题目链接

    C. Ilya And The Tree
    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very interesting tree rooted at vertex 1. There is an integer number written on each vertex of the tree; the number written on vertex i is equal to ai.

    Ilya believes that the beauty of the vertex x is the greatest common divisor of all numbers written on the vertices on the path from the root to x, including this vertex itself. In addition, Ilya can change the number in one arbitrary vertex to 0 or leave all vertices unchanged. Now for each vertex Ilya wants to know the maximum possible beauty it can have.

    For each vertex the answer must be considered independently.

    The beauty of the root equals to number written on it.

    Input
    First line contains one integer number n — the number of vertices in tree (1 ≤ n ≤ 2·105).

    Next line contains n integer numbers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 2·105).

    Each of next n - 1 lines contains two integer numbers x and y (1 ≤ x, y ≤ n, x ≠ y), which means that there is an edge (x, y) in the tree.

    Output
    Output n numbers separated by spaces, where i-th number equals to maximum possible beauty of vertex i.

    Examples
    input
    2
    6 2
    1 2
    output
    6 6
    input
    3
    6 2 3
    1 2
    1 3
    output
    6 6 6
    input
    1
    10
    output
    10

    题意:给出 (n) 个结点的一棵树,每个结点有权值,每个结点的魅力值就是根结点到该结点的路径上点的 (gcd) ,现可以进行一次操作:将树上某个结点权值变成0,或者保持所有点权值不变,问每个结点可能的最大的魅力值(每个结点的询问独立,即操作可以不同)。

    题解:由于是求 (gcd) ,当前结点的最大值并不能导出子结点最优值,比如

    7

    63 63 63 63 9 7 7
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7

    虽然结点6的最优值为9,但结点7的最优值应该为7.

    所以,此处用一个 (vector)(set) 存到该结点路径上执行一次操作可能得到的所有值,由于因数有限,因此这样做是可以的。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<stack>
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=n-1;i>=a;i--)
    #define pb push_back
    #define fi first
    #define se second
    #define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;
    typedef vector<int> VI;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=2e5+100;
    int head[maxn];
    struct edge
    {
        int to,next;
    }e[maxn*2];   //
    int tol=0;
    void add(int u,int v)
    {
        e[++tol].to=v,e[tol].next=head[u],head[u]=tol;
    }
    int v[maxn];
    int d[maxn];
    VI g[maxn]; //g[u]用于存从根结点到结点u执行一次操作可能得到的gcd集合
    int gcd(int a,int b)
    {
        if(a<b) swap(a,b);
        return b==0? a:gcd(b,a%b);
    }
    void dfs(int u,int f)
    {
        d[u]=gcd(d[f],v[u]);
        for(int i=0;i<g[f].size();i++)
        {
            g[u].pb(gcd(g[f][i],v[u]));
        }
        g[u].pb(d[f]);
        sort(g[u].begin(),g[u].end());
        g[u].erase(unique(g[u].begin(),g[u].end()),g[u].end());
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(v==f) continue;
            dfs(v,u);
        }
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        rep(i,1,n+1) scanf("%d",&v[i]);
        rep(i,1,n)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v),add(v,u);
        }
        dfs(1,0);
        rep(i,1,n+1)
        {
            if(!g[i].empty())
                d[i]=max(d[i],g[i].back());
            printf("%d ",d[i]);
        }
        puts("");
        return 0;
    }
    
  • 相关阅读:
    数组方法的扩展,如map,reduce,fliter,forEach方法
    设计模式总体概括
    centos yum 安装 tomcat
    idea springboot 打包 war
    idea使用tomcat运行maven打包的war
    CentOS 7 用 yum 安装 Nginx
    CentOS更换yum源
    城市代码表mysql
    更改idea启动内存信息
    (三)多表代码生成
  • 原文地址:https://www.cnblogs.com/tarjan/p/7452909.html
Copyright © 2011-2022 走看看