zoukankan      html  css  js  c++  java
  • CodeForces

    You are given a tree consisting of n vertices. A number is written on each vertex; the number on vertex i is equal to ai

    .

    Let's denote the function g(x,y)

    as the greatest common divisor of the numbers written on the vertices belonging to the simple path from vertex x to vertex y (including these two vertices). Also let's denote dist(x,y) as the number of vertices on the simple path between vertices x and y, including the endpoints. dist(x,x)=1 for every vertex x

    .

    Your task is calculate the maximum value of dist(x,y)

    among such pairs of vertices that g(x,y)>1

    .

    Input

    The first line contains one integer n

    — the number of vertices (1n2105)

    .

    The second line contains n

    integers a1, a2, ..., an (1ai2105)

    — the numbers written on vertices.

    Then n1

    lines follow, each containing two integers x and y (1x,yn,xy) denoting an edge connecting vertex x with vertex y

    . It is guaranteed that these edges form a tree.

    Output

    If there is no pair of vertices x,y

    such that g(x,y)>1, print 0. Otherwise print the maximum value of dist(x,y)

    among such pairs.

    Examples
    Input
    3
    2 3 4
    1 2
    2 3
    Output
    1
    Input
    3
    2 3 4
    1 3
    2 3
    Output
    2
    Input
    3
    1 1 1
    1 2
    2 3
    Output
    0

    题意:让你求最长的路径长度,满足路上gcd不为1;

    思路:分治的做法比较暴力,但是时限比较长,有板子就直接上了。 由于gcd具有收敛性,路径上的gcd不会太多,而且越远回越接近1,我们记录每一个gcd的最深的位置即可。  (我用的以前的板子,所以用了map,此题的数据量可以不用map

    还有一个思路,我们枚举素因子,然后把含有这个素因子的点标记出来,求他们的最远距离,更新答案。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=200010;
    const int inf=0x7FFFFFFF;
    int Laxt[maxn],Next[maxn<<1],To[maxn<<1],cnt,N,sn;
    int a[maxn],sz[maxn],son[maxn],vis[maxn],root,res;
    int dep[maxn];
    ll ans[maxn];
    map<int,int>mp,tp;
    map<int,int>::iterator it1,it2;
    inline void read(int &x) {
        x=0; char c=getchar();
        while(c>'9'||c<'0') c=getchar();
        while(c<='9'&&c>='0') x=(x<<3)+(x<<1)+c-'0',c=getchar();
    }
    void add(int u,int v){
        Next[++cnt]=Laxt[u];
        Laxt[u]=cnt; To[cnt]=v;
    }
    void getroot(int u,int fa) //找重心
    {
        sz[u]=1; son[u]=0;
        for(int i=Laxt[u];i;i=Next[i]){
            if(To[i]!=fa&&!vis[To[i]]){
                getroot(To[i],u);
                sz[u]+=sz[To[i]];
                son[u]=max(son[u],sz[To[i]]);
            }
        }
        son[u]=max(son[u],sn-son[u]);
        if(root==0||son[root]>son[u]) root=u;
    }
    void getans(int u,int fa,int num) //对于当前链产生的新GCD
    {
        dep[u]=dep[fa]+1; tp[num]=max(tp[num],dep[u]);
        for(int i=Laxt[u];i;i=Next[i]){
            if(!vis[To[i]]&&To[i]!=fa){
                getans(To[i],u,__gcd(num,a[To[i]]));
            }
        }
    }
    void solve(int u) //解决以u为根的子问题
    {
        mp.clear(); mp[a[u]]=1; ans[a[u]]++; dep[u]=1;
        for(int i=Laxt[u];i;i=Next[i])
          if(!vis[To[i]]) {
             tp.clear(); getans(To[i],u,__gcd(a[u],a[To[i]]));
             for(it1=mp.begin();it1!=mp.end();it1++)
               for(it2=tp.begin();it2!=tp.end();it2++){
                  int g=__gcd((*it1).first,(*it2).first);
                  if(g>1) res=max(res,(*it1).second+(*it2).second-1);
            }
            for(it2=tp.begin();it2!=tp.end();it2++)
              mp[(*it2).first]=max((*it2).second,mp[(*it2).first]);
        }
    }
    void dfs(int u)  //分治
    {
        vis[u]=1;  solve(u);
        for(int i=Laxt[u];i;i=Next[i]){
            if(vis[To[i]]) continue;
            root=0; sn=sz[To[i]];
            getroot(To[i],0); dfs(root);
        }
    }
    int main()
    {
        read(N); int u,v,Max=0;
        for(int i=1;i<=N;i++) read(a[i]),Max=max(Max,a[i]);
        for(int i=1;i<N;i++) {
            read(u);read(v);
            add(u,v);  add(v,u);
        }
        if(Max>1) res=1;
        root=0; sn=N; getroot(1,0); dfs(root);
        printf("%d
    ",res);
        return 0;
    }
  • 相关阅读:
    AngularJS使用angular-formly进行表单验证
    AngularJS使用ngMessages进行表单验证
    AngularJS订阅API服务
    AngularJS中module的导入导出
    Gulp快速入门
    AngularJS过滤排序思路
    AngularJS表单验证,手动验证或自动验证
    AngularJS的增删改查、state嵌套案例,不涉及服务端
    前端使用AngularJS的$resource,后端ASP.NET Web API,实现分页、过滤
    前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10258712.html
Copyright © 2011-2022 走看看