CF1101D GCD Counting

时间:2019-06-18
本文章向大家介绍CF1101D GCD Counting,主要包括CF1101D GCD Counting使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

思路:

首先预处理分解因子然后树形dp。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 200005;
 4 int a[N];
 5 vector<int> G[N], F[N], dp[N];
 6 void fac(int x)
 7 {
 8     for (int i = 2; i * i <= a[x]; i++)
 9     {
10         if (a[x] % i == 0)
11         {
12             F[x].push_back(i);
13             dp[x].push_back(1);
14         }
15         while (a[x] % i == 0) a[x] /= i;
16     }
17     if (a[x] != 1) { F[x].push_back(a[x]); dp[x].push_back(1); }
18 }
19 void dfs(int u, int f, int& maxn)
20 {
21     for (int i = 0; i < G[u].size(); i++)
22     {
23         int v = G[u][i];
24         if (v == f) continue;
25         dfs(v, u, maxn);
26         for (int j = 0; j < F[u].size(); j++)
27         {
28             for (int k = 0; k < F[v].size(); k++)
29             {
30                 if (F[u][j] == F[v][k])
31                 {
32                     maxn = max(maxn, dp[u][j] + dp[v][k]);
33                     dp[u][j] = max(dp[u][j], dp[v][k] + 1);
34                 }
35             }
36         }
37     }
38 }
39 int main()
40 {
41     ios::sync_with_stdio(false);
42     int n, x, y;
43     while (cin >> n)
44     {
45         bool flg = true;
46         for (int i = 1; i <= n; i++)
47         {
48             F[i].clear(); dp[i].clear(); G[i].clear();
49             cin >> a[i];
50             if (a[i] != 1) flg = false;
51             fac(i);
52         }
53         for (int i = 1; i < n; i++)
54         {
55             cin >> x >> y;
56             G[x].push_back(y);
57             G[y].push_back(x);
58         }
59         if (flg) { cout << 0 << endl; continue; }
60         int maxn = 1;
61         dfs(1, 0, maxn);
62         cout << maxn << endl;
63     }
64     return 0;
65 }

原文地址:https://www.cnblogs.com/wangyiming/p/11043126.html