Max Tree

Given an integer array with no duplicates. A max tree building on this array is defined as follow:

  • The root is the maximum number in the array
  • The left subtree and right subtree are the max trees of the subarray divided by the root number.

Construct the max tree by the given array.

这是lintcode上的一题,每次先确定根结点最大值,然后根据根结点再分割左右两边,然后继续。按照描述是一个递归过程。但是直接用递归是O(nlogn)的平均复杂度,最坏复杂度为O(n^2),即为有序数组时,这题用递归解法在Lintcode上直接爆栈。

所有需要时间和空间复杂度都为O(n)的解法,仔细分析下这题,给出的数组实际是max-tree的一个中序遍历。

每个结点的父结点都比结点值要大,并且结合中序遍历的性质,如果结点为父结点的左孩子,则在数组中是[结点...父结点]这样的顺序,而如果是右结点,则在数组中是[父结点...结点]这样的顺序。而省略号代表的是结点自己的右子树序列(结点为父结点的左孩子的情况),结点自己的左子树序列(结点为父结点的左孩子的情况),所以...的内容中都是比结点值小的。所以结点的父结点是其左边或者右边第一个比它大的值。在结点是父结点的左右孩子的情况下,如何确定父亲结点是哪个呢。按照推理我们选择其中比较小的那个。

时间: 2024-10-25 18:51:38

Max Tree的相关文章

Lintcode-Max Tree

Given an integer array with no duplicates. A max tree building on this array is defined as follow: The root is the maximum number in the array The left subtree and right subtree are the max trees of the subarray divided by the root number. Construct

POJ3237 Tree(树链剖分 边权)

题目大意:指定一颗树上有3个操作:询问操作,询问a点和b点之间的路径上最长的那条边的长度:取反操作,将a点和b点之间的路径权值都取相反数:变化操作,把某条边的权值变成指定的值. #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <map> #include <set>

BZOJ1036 树的统计Count(同时求sum max)

#include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <map> #include <set> #include <vector> #include <cstdio> using namespace std; const int N=30010; s

Aizu 2450 Do use segment tree 树链剖分+线段树

Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show.php?pid=39566 Description Given a tree with n (1 ≤ n ≤ 200,000) nodes and a list of q (1 ≤ q ≤ 100,000) queries, process the queries in order and out

POJ 3237 Tree

题意是在一棵树上 的边上进行三个操作: 1.修改某条变得值 2.反转一条边的值 3.求出一条边上的max; 树上的操作+线段树 翻转的处理比较难 其他都是以前正常的线段树处理 翻转类似LAZY思想 ,然后我们设定MIN ,MAX,因为-MAX就是MIN 了, 线段树用回以前的版本了: 1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <cmath> 5 #inclu

spoj 375 Query on a tree (树链剖分)

Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of the i-th edge to ti or Q

SPOJ - QTREE Query on a tree题解

题目大意: 一棵树,有边权,有两个操作:1.修改一条边的权值:2.询问两点间路径上的边的权值的最大值. 思路: 十分裸的树链剖分+线段树,无非是边权要放到深度大的一端的点上,但是有两个坑爹的地方,改了好久: 1.数组定义10000和40000会TLE,要乘10: 2.以前的树剖求解的最后是这样的: if (deep[x]>deep[y]) swap(x,y); return max(ans,MAX(1,n,id[x],id[y],1)); 但是WA了,膜拜大神后发现这样就AC了: if (x==

QTREE - Query on a tree

QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html 树链剖分入门题 代码如下(附注解): 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define lson (x<<1) 5 #d

SPOJ QTREE Query on a tree --树链剖分

题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. 询问的时候,在从u找到v的过程中顺便查询到此为止的最大值即可. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath&