Codeforces Round #430 (Div. 2) C. Ilya And The Tree
2017-08-30 11:13
477 查看
题意 : 给你一棵树,一个点的美丽程度定义为根节点到这个节点的所有数的 gcd ,你可以将路径中的一个点删掉,求每个点最大的美丽程度是多少。
题解 : 注意到这个题gcd的递减速度是非常快的,每次有效的 gcd 最小下降 为 1 / 2,所以其收敛的速度是 logn 级别的,并且我们发现祖先节点的美丽程度一定大于其后代的美丽程度,又注意到每个点的美丽程度只与其祖先有关系,这是dfs 序 的天然条件,这样我们就可以dfs暴力枚举删掉哪一个数,不会超过 log 个节点。
坑点 : 如果数据中每个数都相等或者子孙都是祖先的倍数的话 gcd 不会收敛对于这种问题我们可以特殊处理一下就可以了。就像下面这样处理一下就可以了 。
if (temp == pre) {
if (pa ==
1) {
if (a[root] > pre) {
res[root] =
a[root];
}
else
res[root] = pre;
}
else
res[root] = pre;
}
ac 代码 :
题解 : 注意到这个题gcd的递减速度是非常快的,每次有效的 gcd 最小下降 为 1 / 2,所以其收敛的速度是 logn 级别的,并且我们发现祖先节点的美丽程度一定大于其后代的美丽程度,又注意到每个点的美丽程度只与其祖先有关系,这是dfs 序 的天然条件,这样我们就可以dfs暴力枚举删掉哪一个数,不会超过 log 个节点。
坑点 : 如果数据中每个数都相等或者子孙都是祖先的倍数的话 gcd 不会收敛对于这种问题我们可以特殊处理一下就可以了。就像下面这样处理一下就可以了 。
if (temp == pre) {
if (pa ==
1) {
if (a[root] > pre) {
res[root] =
a[root];
}
else
res[root] = pre;
}
else
res[root] = pre;
}
ac 代码 :
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <vector> #define ll long long using namespace std; const int maxn = 2e5 + 10; int a[maxn] = {0}; vector <int> G[maxn]; vector <int> g[maxn]; vector <int> v; bool vis[maxn] = {0}; int res[maxn] = {0}; int pos = 0; int mx = 0; int cnt = 0; void dfs1 (int root) { int k = G[root].size(); for (int i = 0;i < k; ++ i) { int u = G[root][i]; if (!vis[u]) { g[root].push_back(u); vis[u] = 1; dfs1 (u); } } } void dfs2 (int pa,int root,int pre) { int k = g[root].size(); if (!vis[root]){ v.push_back (root); vis[root] = 1; } if (pre == 1) { if (pa == 1) { res[root] = a[root]; for (int i = 0;i < k; ++ i) { int u = g[root][i]; dfs2 (root,u,a[root]); } } else { res[root] = 1; for (int i = 0;i < k; ++ i) { int u = g[root][i]; dfs2 (root,u,1); } } v.pop_back(); return ; } int temp = __gcd(a[root],pre); if (temp == pre) { if (pa == 1) { if (a[root] > pre) { res[root] = a[root]; } else res[root] = pre; } else res[root] = pre; } else { int y = v.size(); int ans = 0; int sum = 0; for (int i = 0;i < y; ++ i) { sum = 0; for (int j = 0;j < y; ++ j) { if (j == i) continue; sum = __gcd(sum,a[v[j]]); } ans = max(ans,sum); } res[root] = ans; } for (int i = 0;i < k; ++ i){ dfs2 (root,g[root][i],res[root]); } v.pop_back(); } int main () { int n; scanf ("%d",&n); for (int i =1 ;i <= n ;++ i) scanf ("%d",a + i); for (int i = 0;i < n - 1; ++ i) { int x,y; scanf ("%d%d",&x,&y); G[x].push_back(y); G[y].push_back(x); } vis[1] = 1; dfs1 (1); // cout << g[2].size() << endl; res[1] = a[1]; int k = g[1].size(); memset (vis,0,sizeof (vis)); for (int i = 0;i < k; ++ i) { int u = g[1][i]; vis[1] = 1; v.push_back (1); dfs2 (1,u,a[1]); v.pop_back(); } for (int i = 1;i <= n; ++ i) { printf ("%d ",res[i]); } return 0; }
相关文章推荐
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree(dfs)
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree(dfs+最大公约数+因子+树)
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2)-搜索&STL-Ilya And The Tree
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) Ilya And The Tree 树上因子 思维 + dfs
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C Ilya And The Tree SET暴力
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree(补题)
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree
- Codeforces Round #430 (Div. 2) 842C Ilya And The Tree(暴力)
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree 树dp 统计
- Codeforces Round #430 (Div. 2) C. Ilya And The Tree dfs+set
- 【Codeforces Round #430 (Div. 2) C】Ilya And The Tree