GCD Counting - codeforce

题解

\(a_i \leq 2 * 10^5\),所以每个\(a\)的质因数个数少于19个。保存每个结点的质因数,然后暴力更新每个结点的\(maxCnt(u,p_i)\)。并且同时记录答案。

\(maxCnt(u, p_i):=\)结点\(u\)的质因数\(p_i\)在以\(u​\)为根的子树中最长的路径(以根为起点的到某点的路径)的长度。

代码来源:https://www.cnblogs.com/xht37/archive/2018/12.html

代码

const int N = 200005;

int n;
int ans = 1;

bool flag = 1;

vector<int> p[N], c[N], G[N];

void Update(int u, int v) {
    rep(i, 0, Size(p[u])) rep(j, 0, Size(p[v])) if (p[u][i] == p[v][j]) {
        ans = max(ans, c[u][i] + c[v][j]);        // 更新答案
        c[u][i] = max(c[u][i], c[v][j] + 1);         // 更新 maxCnt
    }
}

void Divide(int x, int t) {
    for (int i = 2; i * i <= x; ++i) if (x % i == 0) {
        p[t].pb(i);
        c[t].pb(1);
        while(x % i == 0) x /= i;
    }
    if (x > 1) {
        p[t].pb(x);
        c[t].pb(1);
    }
}

void DFS(int u, int pa) {
    for (auto v : G[u]) if (v != pa) {
        DFS(v, u);
        Update(u, v);
    }
}

int main()
{
    cin >> n;
    Rep(i, 1, n) {
        int x;
        cin >> x;
        Divide(x, i);
        if (x != 1) flag = 0;
    }
    rep(i, 1, n) {
        int u, v;
        cin >> u >> v;
        G[u].pb(v);
        G[v].pb(u);
    }
    if (flag) {
        puts("0");
        return 0;
    }
    DFS(1, 0);
    cout << ans << endl;
    return 0;
}



posted @ 2019-01-16 14:04  天之道,利而不害  阅读(189)  评论(0编辑  收藏  举报