GCD Counting

题解

(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;
}



原文地址:https://www.cnblogs.com/zgglj-com/p/10276685.html