CF 842C Ilya And The Tree(树上DFS)

题目链接:http://codeforces.com/problemset/problem/842/C

题目:

Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very interesting tree rooted at vertex 1. There is an integer number written on each vertex of the tree; the number written on vertex i is equal to ai.

Ilya believes that the beauty of the vertex x is the greatest common divisor of all numbers written on the vertices on the path from the root to x, including this vertex itself. In addition, Ilya can change the number in one arbitrary vertex to 0 or leave all vertices unchanged. Now for each vertex Ilya wants to know the maximum possible beauty it can have.

For each vertex the answer must be considered independently.

The beauty of the root equals to number written on it.

Input

First line contains one integer number n — the number of vertices in tree (1 ≤ n ≤ 2·105).

Next line contains n integer numbers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 2·105).

Each of next n - 1 lines contains two integer numbers x and y (1 ≤ x, y ≤ nx ≠ y), which means that there is an edge (x, y) in the tree.

Output

Output n numbers separated by spaces, where i-th number equals to maximum possible beauty of vertex i.

Examples

input

26 21 2

output

6 6 

input

36 2 31 21 3

output

6 6 6 

input

110

output

10 

题意:给定一棵树,根为1。求各顶点从根到该顶点路径上所有顶点的gcd(路径上可以使其中一个顶点为0)。

题解:以集合的形式,进行操作。该点可能的答案是其父亲节点可能的答案与该点的GCD 或 使该点为0的GCD 或 整条路径上不置0的GCD。放一个集合里,然后取最大值。

从这个题目中学到好多新科技哇!

1.首先是auto,自动判断数据类型,对于STL的各种容器就很方便。

2.集合set 的rbegin()函数

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define PI acos(-1.0)
 5 #define INF 0x3f3f3f3f
 6 #define FAST_IO ios::sync_with_stdio(false)
 7 #define CLR(arr,val) memset(arr,val,sizeof(arr))
 8
 9 typedef long long LL;
10 const int N=2*1e5+1000;
11 int a[N];
12 set <int> s[N];
13 vector <int> E[N];
14
15 void DFS(int u,int Fa,int GCD){
16     for(auto i:s[Fa]) s[u].insert(__gcd(i,a[u]));
17     s[u].insert(GCD);
18     GCD=__gcd(GCD,a[u]);
19     s[u].insert(GCD);
20     for(auto i:E[u]){
21         if(i!=Fa) DFS(i,u,GCD);
22     }
23 }
24
25 int main(){
26     int n,x,y;
27     scanf("%d",&n);
28     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
29     for(int i=1;i<n;i++){
30         scanf("%d %d",&x,&y);
31         E[x].push_back(y);
32         E[y].push_back(x);
33     }
34     DFS(1,0,0);
35     for(int i=1;i<=n;i++){
36         printf("%d ",*s[i].rbegin());
37     }
38     return 0;
39 }

原文地址:https://www.cnblogs.com/Leonard-/p/8215812.html

时间: 2024-10-12 04:05:54

CF 842C Ilya And The Tree(树上DFS)的相关文章

codeforces 842C Ilya And The Tree (01背包+dfs)

(点击此处查看原题) 题目分析 题意:在一个树中,有n个结点,记为 1~n ,其中根结点编号为1,每个结点都有一个值val[i],问从根结点到各个结点的路径中所有结点的值的gcd(最大公约数)最大是多少,其中,我们可以将路径中某一个结点的值变为0,也可以选择不变. 思路:注意到对于每个结点,我们可以选择这个结点,或者不选这个结点(将权值记为0),因而有点01背包的感觉,而我们求gcd的时候需要取所有情况中的最大值 那么我们从根结点开始,每经过一个结点,就从其父节点的所有情况转移得到当前结点的状态

POJ 3321 Apple Tree (dfs+线段树)

题目大意: 修改树上的节点,然后求子树的和. 思路分析: dfs 重新编号,烂大街了... #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define maxn 100005 #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e using namespace std

POJ 2468 Apple Tree 树上瞎搞分组背包

昨晚Debug了好久始终找不出哪里错了,今早再一看发现自己已荣升逗比Beta 2.0 Version. 个人感觉此题为HDU 4003 的弱化版. 把每棵子树都看成一类商品,在每类商品中至多选一件.则问题转化为最基本的分组背包问题. dp[s][c][k] c == 1时,表示在s结点不返回时走K的最大收益,c == 0时,表示在s结点重新返回时走k步的最大收益. 可以dfs从底到顶更新dp.值得一提的是,要保证每个结点的dp[s][c][k]只会被dfs一次,即不能重复更新. 因为重复的dfs

CodeForces - 383C Propagating tree(dfs + 线段树)

题目大意: 给出一棵树,树上每个节点都有权值,然后有两个操作. 1 x val 在结点x上加上一个值val,x的儿子加上 -val,x的儿子的儿子加上 - (-val),以此类推. 2 x 问x节点的值. 思路分析: 每个节点上加值都是给自己的儿子节点加,而且这个是颗树. 比如样例上的,如果你给node 1加一个值,那么五个节点都加. 再给node 2加个值,2的儿子节点也加了,之前给1加的值也要加到2号节点的儿子. 所以你会发现节点的儿子会存在一个从属的关系. 这样的话,我们可以把所有节点从新

C. Ilya And The Tree 树形dp 暴力

C. Ilya And The Tree 写法还是比较容易想到,但是这么暴力的写法不是那么的敢写. 就直接枚举了每一个点上面的点的所有的情况,对于这个点不放进去特判一下,然后排序去重提高效率. 注意dp[v]一开始存的是从根节点到这个节点都选的情况,这样才好往后转移. #include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <cstrin

[hdu5593 ZYB&#39;s Tree] 树上统计

题意:给1棵N(≤500,000)个节点的树,每条边边权为1,求距离每个点距离不超过K(K≤10)的点的个数的xor和. 思路:由于K很小,可以考虑把距离作为状态的一部分,然后研究父子之间状态的联系.令ans[i][j]表示与i的距离为j的点的个数,那么ans[i][j]由两部分构成,一部分来源于子树,一部分来源于父亲,那么令f[i][j]表示从子树来的答案,g[i][j]表示从父亲来的答案,son(i)表示i的儿子,fa(i)表示i的父亲,则有: ans[i][j] = f[i][j] + g

2014 Super Training #9 F A Simple Tree Problem --DFS+线段树

原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个mark坑了我好几个小时..哎.太弱. 先DFS这棵树,树形结构转换为线性结构,每个节点有一个第一次遍历的时间和最后一次遍历的时间,之间的时间戳都为子树的时间戳,用线段树更新这段区间即可实现更新子树的效果,用到懒操作节省时间. 坑我的地方: update时,不能写成:tree[rt].mark = 1,

HDU2489 Minimal Ratio Tree 【DFS】+【最小生成树Prim】

Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2382    Accepted Submission(s): 709 Problem Description For a tree, which nodes and edges are all weighted, the ratio of it is

Atcoder #017 agc017 D.Game on Tree 树上NIM 博弈

LINK 题意:树上NIM的模板题,给出一颗树,现有操作删去端点不为根节点的边,其另一端节点都将被移除,不能取者为败 思路:一看就是个NIM博弈题,只是搬到树上进行,树上DFS进行异或 记得#014D题也是一模一样的博弈...巨水 比赛B题没想出来先做了这题:P /** @Date : 2017-07-09 21:15:04 * @FileName: D 树上删边 NIM 博弈.cpp * @Platform: Windows * @Author : Lweleth ([email protec