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. Linux学习(四)档案与目录管理

    1. 目录与路径  1.1 相对路径与绝对路径  1.2 目录的相关操作: cd, pwd, mkdir, rmdir  1.3 关于执行文件路径的变量: $PATH2. 档案与目录管理  2.1 档 ...

  2. kerberos认证协议分析

    Kerberos认证协议分析 Kerberos认证协议流程 如上图: * 第一步:client和认证服务器(AS)通信完成认证过程,如果认证成功AS返回给client一个TGT(用来向TGS获取tic ...

  3. 巡风代码架构简介以及Flask的项目文件结构简介

    一.巡风: 巡风是一款什么东西,想必安全同行都不陌生吧.用它作为内网漏洞扫描管理架构是一种很好的选择,扫描快,开源,还可自己编写符合规则的POC直接放入相应目录来扩展.今天下午趁着有点时间捋了一下巡风 ...

  4. c# SQL Server数据库操作-数据适配器类:SqlDataAdapter

    SqlDataAdapter类主要在MSSQL与DataSet之间执行数据传输工具,本节将介绍如何使用SqlDataAdapter类来填充DataSet和MSSQL执行新增.修改..删除等操作. 功能 ...

  5. 微信小程序 --- 动态获取input的value

    这里对 input 使用的是 bindinput 方法: <input type="text" bindinput="input"> <but ...

  6. js获取当前域名

    <script language="javascript"> //获取域名 host = window.location.host; host2=document.do ...

  7. 用 mongodb 储存多态消息/提醒类数据(转)

    原文:http://codecampo.com/topics/66 前天看到 javaeye 计划采用mongoDB实现网站全站消息系统,很有同感,mongodb 很适合储存消息类数据.之前讨论了如何 ...

  8. 测试命令运行时间:timeit和profile

    先说timeit from timeit import Timer def test1(): n=0 for i in range(101): n+=i return n def test2(): r ...

  9. Java-idea-FindBugs、PMD和CheckStyle对比

    一.对比 工具 目的 检查项 备注 FindBugs 检查.class 基于Bug Patterns概念,查找javabytecode (.class文件)中的潜在bug 主要检查bytecode中的 ...

  10. 前端错误提示whitelabel error page

    1:错误提示whitelabel error page:需要定义一个error.html  ,否则提示如图