题目链接

题意

给定一棵根为\(1\)的树。定义每个点的美丽值为根节点到它的路径上所有点的\(gcd\)值。但是对于每个点,在计算它的美丽值时,可以将这条路径上某个点的值变为\(0\)来最大化它的美丽值。现问每个点的美丽值最大是多少。

注意,每个点的美丽值计算是独立的,即每次可以选择变为\(0\)的点可以是不同的。

思路

对于某一条路径,考虑上面变化的点。

如果变为\(0\)的是,

根节点

那么可以直接一路往下ans0[v]=gcd(ans0[u],val[v]);(\(u\)是\(v\)的父亲节点);

非根节点

如果不是根节点,而是中间不知道哪一个点,那该怎么办呢?

要想到的是,此时也是有一个不变量的,那就是根——根节点的权值始终不会改变,也就是说整条路径不管怎么变,最终的\(gcd\)值都是根节点的权值的因子

因此,可以预处理出根节点的所有因子,然后\(dfs\)的时候统计路径上的每个因子的个数。对于一个深度为\(dep\)的点来说,只有当根节点到它的路径上某个因子的出现次数\(\geq dep-1\),这个因子才可能是满足条件的\(gcd\). 从大到小枚举即可。

Code

#include <bits/stdc++.h>
#define maxn 200010
using namespace std;
typedef long long LL;
struct Edge {
int to, ne;
Edge(int _to=0, int _ne=0): to(_to), ne(_ne) {}
}edge[maxn * 2];
int tot, t, ne[maxn], ans0[maxn], ans1[maxn], val[maxn], cnt[maxn], divi[maxn];
void add(int u, int v) {
edge[tot] = Edge(v, ne[u]);
ne[u] = tot++;
}
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
void accum(int x, bool sgn) {
for (int i = 0; i < t; ++i) {
if (x % divi[i] == 0) if (sgn==1) ++cnt[i]; else --cnt[i];
}
}
void dfs(int u, int fa, int dep) {
for (int i = ne[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
if (v == fa) continue;
ans0[v] = gcd(ans0[u], val[v]);
accum(val[v], 1);
for (int j = t-1; j >= 0; --j) if (cnt[j] >= dep) { ans1[v] = divi[j]; break; }
dfs(v, u, dep+1);
accum(val[v], 0);
}
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &val[i]);
memset(ne, -1, sizeof(ne));
for (int i = 1; i < n; ++i) {
int x, y;
scanf("%d%d", &x, &y);
add(x, y), add(y, x);
}
for (int i = 1; i*i <= val[1]; ++i) {
if (i*i == val[1]) divi[t++] = i;
else if (val[1]%i==0) divi[t++] = i, divi[t++] = val[1]/i;
}
ans0[1] = 0;
sort(divi, divi+t);
dfs(1, -1, 0);
printf("%d", val[1]);
for (int i = 2; i <= n; ++i) printf(" %d", max(ans0[i], ans1[i])); printf("\n");
return 0;
}

Codeforces 842C Ilya And The Tree 树上gcd的更多相关文章

  1. codeforces 842C Ilya And The Tree

    Ilya is very fond of graphs, especially trees. During his last trip to the forest Ilya found a very ...

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

    (点击此处查看原题) 题目分析 题意:在一个树中,有n个结点,记为 1~n ,其中根结点编号为1,每个结点都有一个值val[i],问从根结点到各个结点的路径中所有结点的值的gcd(最大公约数)最大是多 ...

  3. XJOI 3363 树4/ Codeforces 739B Alyona and a tree(树上差分+路径倍增)

    D. Alyona and a tree time limit per test  2 seconds memory limit per test  256 megabytes input  stan ...

  4. Codeforces 739B Alyona and a tree(树上路径倍增及差分)

    题目链接 Alyona and a tree 比较考验我思维的一道好题. 首先,做一遍DFS预处理出$t[i][j]$和$d[i][j]$.$t[i][j]$表示从第$i$个节点到离他第$2^{j}$ ...

  5. CodeForces 812E Sagheer and Apple Tree 树上nim

    Sagheer and Apple Tree 题解: 先分析一下, 如果只看叶子层的话. 那么就相当于 经典的石子问题 nim 博弈了. 那我们看非叶子层. 看叶子层的父亲层. 我们可以发现, 如果从 ...

  6. Codeforces Round #430 (Div. 2) C. Ilya And The Tree

    地址:http://codeforces.com/contest/842/problem/C 题目: C. Ilya And The Tree time limit per test 2 second ...

  7. Codeforces E. Alyona and a tree(二分树上差分)

    题目描述: Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  8. 【cf842C】 Ilya And The Tree(dfs、枚举因子)

    C. Ilya And The Tree 题意 给一棵树求每个点到根的路上允许修改一个为0,gcd的最大值. 题解 g是从根到当前点允许修改的最大gcd,gs为不修改的最大gcd.枚举当前点的因子,更 ...

  9. C. Ilya And The Tree 树形dp 暴力

    C. Ilya And The Tree 写法还是比较容易想到,但是这么暴力的写法不是那么的敢写. 就直接枚举了每一个点上面的点的所有的情况,对于这个点不放进去特判一下,然后排序去重提高效率. 注意d ...

随机推荐

  1. 远程连接 mySql数据库

    远程连接 mySql数据库 一.安装并配置MySQL1.安装MySQL:运行mysql-essential-6.0.11-alpha-win32,按“MySQL+6.0+Windows下安装图解”完成 ...

  2. Map集合应用 取出一个字符串中字母出现的次数。如:字符串:"abcdekka27qoq" ,输出格式为:a(2)b(1)k(2)...

    package com.swift; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import ...

  3. c++作业:递归调用,例题4.5 求第五个人的年龄

    递归调用,例题4.5 求第五个人的年龄 #include <iostream> using namespace std; int age(int num){ int a; ) a=; el ...

  4. C++ 学习笔记(五)类的知识小结一(重载,友元函数,静态成员,new)

    ---恢复内容开始--- 学习C++类知识点还是挺多的,每个知识点学习的时候都觉得这个知识点咋那么多东西,其实真学完了再回头看好像也就那么点.这次用程序写一个黑猫揍白猫的故事总结一下这段时间学习的零碎 ...

  5. vue $emit子组件传出多个参数,如何在父组件中在接收所有参数的同时添加自定义参数

    Vue.js 父子组件通信的十种方式 前言 很多时候用$emit携带参数传出事件,并且又需要在父组件中使用自定义参数时,这时我们就无法接受到子组件传出的参数了.找到了两种方法可以同时添加自定义参数的方 ...

  6. CodeForces - 899E Segments Removal (优先队列 + 链表)

    给定一个序列,每次从序列中找一个长度最大的元素相同的片段,删除它. 如果长度相同,删除最靠左边的那个片段. 问,需要删几次. 用链表处理删除片段.对于删除之后两边又能连成一个片段的那种情况,用set记 ...

  7. vmware10下载地址

    https://download3.vmware.com/software/wkst/file/VMware-Workstation-Full-10.0.1-1379776.x86_64.bundle ...

  8. P2014 选课(树形背包)

    P2014 选课 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有 ...

  9. web安全测试---AppScan扫描工具(转)

    安全测试应该是测试中非常重要的一部分,但他常常最容易被忽视掉. 尽管国内经常出现各种安全事件,但没有真正的引起人们的注意.不管是开发还是测试都不太关注产品的安全.当然,这也不能怪我们苦B的“民工兄弟” ...

  10. Leetcode28--->字符串的匹配(KMP)

    题目: 题目的本质是给定两个字符串str1,str2,求str1中的str2串开始的地方,即字符串的匹配,KMP算法 思路:时间复杂度为O(m + n),空间复杂度为O(n),原串的长度为m,子串的长 ...