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;
    }
  • 相关阅读:
    HDU 5492 Find a path
    codeforce gym 100548H The Problem to Make You Happy
    Topcoder SRM 144 Lottery
    codeforce 165E Compatible Numbers
    codeforce gym 100307H Hack Protection
    区间DP总结
    UESTC 1321 柱爷的恋爱 (区间DP)
    HDU 4283 You Are the One (区间DP)
    HDU 2476 String painter (区间DP)
    UESTC 426 Food Delivery (区间DP)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10258712.html
Copyright © 2011-2022 走看看