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. Android 判断是否是Rtl

    第一种方法: private boolean isRtl() { return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) ...

  2. Egret3D学习笔记一 (Unity插件使用)

    一 官方教程: http://developer.egret.com/cn/github/egret-docs/Engine3D/getStarted/getStarted/index.html 大部 ...

  3. iOS - 开发中调试小技巧

    对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不同语言.不同IDE.不同平台的 ...

  4. SpringMVC实现简单应用

    我们都知道,servlet代码一般来说只能在一个servlet中做判断去实现一个servlet响应多个请求, 但是springMVC的话还是比较方便的,主要有两种方式去实现一个controller里能 ...

  5. Spring项目对JDBC的支持和基本使用

    欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...

  6. vue 缓存的keepalive页面刷新数据

    用到这个的业务场景是这样的: a页面点击新建列表按钮进入到新建的页面b,填写b页面并点击b页面确认添加按钮,把这些数据带到a页面,填充到列表(数组),可以添加多条, 点击这条的时候进入到编辑页面,确认 ...

  7. Lucene.net的简单使用

    一.Lucene.net的简单介绍 1.为什么要使用Lucene.net       使用like的模糊查询,模糊度太低,中间添加几个字就无法查找.同时会造成数据库的全文检索,效率低下,数据库服务器造 ...

  8. Process Monitor分析某个应用行为

    1.打开Process Mointor 2.点击filter-->filter   在弹出的对话框中Architecture 下拉框,选择Process Name 填写要分析的应用程序名字. 点 ...

  9. SQLPlus的两种登录方式的不同效果

    Windows 8,Oralce11g,命令行 1.输入“sqlplus”,回车,提示:请输入用户名,输入用户名,回车,提示,请输入口令,输入口令后,回车,报ORA-12560:TNS:协议适配器错误 ...

  10. 40个DBA日常维护的SQL脚本

    1.查询碎片程度高的表 条件为什么block>100,因为一些很小的表,只有几行数据实际大小很小,但是block一次性分配就是5个(11g开始默认一次性分配1M的block大小了,见create ...