Problem E. TeaTree

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 722    Accepted Submission(s): 255

Problem Description
Recently, TeaTree acquire new knoledge gcd (Greatest Common Divisor), now she want to test you.
As we know, TeaTree is a tree and her root is node 1, she have n nodes and n-1 edge, for each node i, it has it’s value v[i].
For every two nodes i and j (i is not equal to j), they will tell their Lowest Common Ancestors (LCA) a number : gcd(v[i],v[j]).
For each node, you have to calculate the max number that it heard. some definition:
In graph theory and computer science, the lowest common ancestor (LCA) of two nodes u and v in a tree is the lowest (deepest) node that has both u and v as descendants, where we define each node to be a descendant of itself.
 
Input
On the first line, there is a positive integer n, which describe the number of nodes.
Next line there are n-1 positive integers f[2] ,f[3], …, f[n], f[i] describe the father of node i on tree.
Next line there are n positive integers v[2] ,v[3], …, v[n], v[i] describe the value of node i.
n<=100000, f[i]<i, v[i]<=100000
 
Output
Your output should include n lines, for i-th line, output the max number that node i heard.
For the nodes who heard nothing, output -1.
 
求树上每点的一个值
这个值 是 该点 以及它的子树所有点的 最大gcd
 
#include <iostream>
#include <vector> #define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=a-1;i>=b;i--) const int MX = 1e5;
const int MXX = *MX;
using namespace std; int n; vector<int> G[MX+],vv[MX+]; // init函数 实现将i因数分解 (i < 1e5)
void init() {
rep(i,,MX+) vv[i].push_back();
rep(i,,MX+) {
vv[i].push_back(i);
for(int j=i+i;j<=MX;j+=i) vv[j].push_back(i);
} // rep(i,1,MX+1) {
// rep(j,0,vv[i].size()) {
// printf("%d ",vv[i][j]);
// }puts("");
// }
} int root[MX+],ls[MXX],rs[MXX],sum[MXX],rear,ans[MX]; inline void push_up(int rt) {
if(ls[rt] && rs[rt]) sum[rt] = max(sum[ls[rt]],sum[rs[rt]]);
else if(ls[rt]) sum[rt] = sum[ls[rt]];
else if(rs[rt]) sum[rt] = sum[rs[rt]];
} void update(int &rt,int l,int r,int p) {
if(rt==) rt = ++rear;
if(l == r) {
sum[rt] = p;
return ;
}
int m = (l+r)>>;
if(p <= m) update(ls[rt],l,m,p);
else update(rs[rt],m+,r,p);
push_up(rt);
} int merge(int rt, int prt, int &ans) {
if(rt== || prt==) return rt^prt;
//这里维护最大的gcd
if(sum[rt] == sum[prt]) ans = max(ans,sum[rt]);
//这里只有有因子,就归并到rt上面
if(ls[rt] | ls[prt]) ls[rt] = merge(ls[rt], ls[prt], ans);
if(rs[rt] | rs[prt]) rs[rt] = merge(rs[rt], rs[prt], ans);
push_up(rt);
return rt;
} void dfs(int u) {
ans[u] = -;
rep(i, , G[u].size()) {
int v = G[u][i];
dfs(v);
root[u] = merge(root[u],root[v],ans[u]);
}
} int main () {
freopen("in.txt" ,"r",stdin);
freopen("out.txt","w",stdout);
init(); scanf("%d", &n);
//建边
rep(i,,n+) {
int fa; scanf("%d",&fa);
G[fa].push_back(i);
}
//对每个v[i]建线段树
rear=;
rep(i,,n+) {
int x; scanf("%d", &x);
root[i]=;
rep(j, , vv[x].size()) {
update(root[i], , MX, vv[x][j]);
}
}
//暴力更新 gcd
dfs();
//输出答案
rep(i,,n+) printf("%d\n", ans[i]);
return ;
}
 

hdu 6430 线段树 暴力维护的更多相关文章

  1. hdu 4288 线段树 暴力 **

    题意: 维护一个有序数列{An},有三种操作: 1.添加一个元素. 2.删除一个元素. 3.求数列中下标%5 = 3的值的和. 解题思路: 看的各种题解,今天终于弄懂了. 由于线段树中不支持添加.删除 ...

  2. V - Can you answer these queries? HDU - 4027 线段树 暴力

    V - Can you answer these queries? HDU - 4027 这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号. 然后稍微看了一下题解,因为每一个数开根号最多开 ...

  3. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...

  4. hdu 1556 Color the ball(线段树区间维护+单点求值)

    传送门:Color the ball Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/3276 ...

  5. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  6. HDU 2795 线段树单点更新

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. HDU 6218 (线段树+set)

    HDU 6218 Bridge Problem : 给一个2×n的矩阵,一开始矩阵所有相邻点之间有一条边.有其.个询问,每次给出两个相邻的点的坐标,将其中的边删除或者添加,问如此操作之后整张图的割边数 ...

  8. 2018 CCPC 吉林站 H Lovers || HDU 6562 (线段树哦)

    http://acm.hdu.edu.cn/showproblem.php?pid=6562 题意: q次操作 1.将第l~r个数的左边和和右边都加上一个数d, 使得这个数变成 dsiddsid的形式 ...

  9. G - Queue HDU - 5493 线段树+二分

    G - Queue HDU - 5493 题目大意:给你n个人的身高和这个人前面或者后面有多少个比他高的人,让你还原这个序列,按字典序输出. 题解: 首先按高度排序. 设每个人在其前面有k个人,设比这 ...

随机推荐

  1. hihocoder [Offer收割]编程练习赛14 小Hi和小Ho的礼物

    题目1 : 小Hi和小Ho的礼物 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 某人有N袋金币,其中第i袋内金币的数量是Ai.现在他决定选出2袋金币送给小Hi,再选2袋 ...

  2. shell 中的()【】{}(())

    本文转自:https://blog.csdn.net/taiyang1987912/article/details/39551385 shell中各种括号的作用().(()).[].[[]].{} 一 ...

  3. salt-stack更换主机名

    author:headsen  chen date: 2018-09-30  11:22:40 1,建立master端和client端的正常连接 #master yum -y install epel ...

  4. [SQL]批量 更改字符集脚本,批量查询约束,批量查询索引

    How to change collation of all database objects in SQL Server. Have you encountered a problem where ...

  5. ROM和RAM的故事

    在公众号里看到一篇很好的文章讲解rom和ram,之前也是一直不能理解两者的区别,今天就转载记下来吧.也方便大家学习. 因为我刚开始学习的时候总喜欢刨根问底,一个问题要是不搞清楚,后面学习都会很吃力的. ...

  6. 【JavaScript算法】---希尔排序

    一.什么是希尔排序 希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本.   思路:      希尔排序是把记录按下标的一定增量分组,对 ...

  7. 自定义Realm解析

    自定义Realm解析---------------------------------------> /* * Copyright 2005-2013 shopxx.net. All right ...

  8. Eclipse Tomcat插件的配置, 及 Tomcat 的配置

    Eclipse Tomcat插件的配置, 及 Tomcat 的配置   首先下载 对应 eclipse 版本的 tomcat 插件版本,(这里要注意: Tomcat 插件是Tomcat 插件,Tomc ...

  9. The Rise of Database Sharding DATABASE SHARDING

    w玻璃碎片.0共享 http://www.agildata.com/database-sharding/ The Rise of Database Sharding The concept of Da ...

  10. busybox,alphine,ubuntu,centos/fedore操作系统

    在docker 中搜索busybox   docker search busybox 之后我们运行一下这个系统 Alpine操作系统 3.ubuntu 之前一直都安装过,这里不再多叙述 当时用apt- ...