码迷,mamicode.com
首页 > 其他好文 > 详细

CF842C Ilya And The Tree

时间:2017-09-03 15:36:00      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:memset   return   names   log   name   i++   bit   main   过程   

思路:

1. 如果根节点是0,那么可以通过一次dfs计算出所有节点的最大值。

2. 如果根节点不是0,那么其余各点的最大值一定是根节点的一个因子。首先计算出根节点的所有因子。在dfs到一个深度为d的节点v时,遍历所有因子:对于因子x,p表示从根节点到达v的路径中能够被x整除的节点个数。如果p >= d - 1,则x就是当前节点的一个候选最大值(d-1是因为可以把路径中其中一个数替换为0)。

于是通过两次dfs即可得出答案。复杂度O(n * sqrt(n))。在dfs的过程中,要注意维护全局变量。dfs到下一个分支时,要把上一个分支对全局变量造成的影响消除。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[200005], val[200005];
 4 vector<int> tree[200005];
 5 int vis[200005];
 6 int divisors[1005];
 7 
 8 void dfs(int cur, int div)
 9 {
10     vis[cur] = 1;
11     for (int i = 0; i < tree[cur].size(); i++)
12     {
13         int tmp = tree[cur][i];
14         if (vis[tmp]) continue;
15         val[tmp] = __gcd(div, a[tmp]);
16         dfs(tmp, val[tmp]);
17     }
18 }
19 
20 void dfs2(int cur, int d, vector<int>& v)
21 {
22     vis[cur] = 1;
23     for (int i = 0; i < tree[cur].size(); i++)
24     {
25         int tmp = tree[cur][i];
26         if (vis[tmp]) continue;
27          for (int j = 0; j < v.size(); j++)
28         {
29             if (a[tmp] % v[j] == 0) divisors[j]++;
30             if (divisors[j] >= d) val[tmp] = max(val[tmp], v[j]);
31         }
32         dfs2(tmp, d + 1, v);
33         for (int j = 0; j < v.size(); j++)
34             if (a[tmp] % v[j] == 0) divisors[j]--;
35     }
36 }
37 
38 int main()
39 {
40     int n, x, y;
41     while (cin >> n)
42     {
43         for (int i = 1; i <= n; i++)
44             tree[i].clear();
45         for (int i = 1; i <= n; i++)
46             cin >> a[i];
47         for (int i = 0; i < n - 1; i++)
48         {
49             cin >> x >> y;
50             tree[x].push_back(y);
51             tree[y].push_back(x);
52         }
53         int tmp = a[1];
54         a[1] = 0;
55         memset(vis, 0, sizeof vis);
56         dfs(1, 0);
57         a[1] = val[1] = tmp;
58         vector<int> v;
59         for (int i = 1; i * i <= a[1]; i++)
60         {
61             if (a[1] % i == 0)
62             {
63                 v.push_back(i);
64                 if (a[1] / i != i) v.push_back(a[1] / i);
65             }
66         }
67         sort(v.begin(), v.end());
68         for (int i = 0; i < v.size(); i++) divisors[i] = 1;
69         memset(vis, 0, sizeof vis);
70         dfs2(1, 1, v);
71         for (int i = 1; i <= n; i++)
72             cout << val[i] << " ";
73         cout << endl;
74     }
75     return 0;
76 }

 

CF842C Ilya And The Tree

标签:memset   return   names   log   name   i++   bit   main   过程   

原文地址:http://www.cnblogs.com/wangyiming/p/7469569.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!