[Dr.Lib]Note:Data Structures – 左偏树

左偏树真是个超好写的东西!支持合并,插入,删除最小值三个操作。后两个操作都可以看成第一个操作的拓展,如删除最小值是合并根的两棵子树,插入则直接将元素看作一个左偏树——所以只要写个Merge就可以了!

左偏树保证左子树深度大于等于右子树深度,同时符合堆性质。合并LT1,LT2(假设LT1中最小值比LT2小,否则交换)时,递归合并LT1的右子树和LT2替换掉LT1,然后如果LT1不符合左偏性质,则交换LT1的子树。

小小的提示:构树时,逐个插入是O(nlgn)的。这里可以有O(n)的复杂度的算法:先把所有元素构成n个单元素左偏树放进队列,然后每次取出两个合并后放入队列尾,直到只剩下一棵左偏树。

——http://seter.is-programmer.com/posts/30733.html

 

[Dr.Lib]Note:Algorithm – Manhattan minimum spanning tree

Via http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lineSweep

We first break this down into a simpler problem. Standard MST algorithms for general graphs (e.g., Prim's algorithm) can compute the MST in O((E + N) log N) time for E edges. If we can exploit geometric properties to reduce the number of edges to O(N), then this is merely O(N log N). In fact we can consider, for each point P, only its nearest neighbors in each of the 8 octants of the plane (see the figure below). The figure shows the situation in just one of the octants, the West-Northwest one. Q is the closest neighbour (with the dashed line indicating points at the same Manhattan distance as Q), and R is some other point in the octant. If PR is an edge in a spanning tree, then it can be removed and replaced by either PQ or QR to produce a better spanning tree, because the shape of the octant guarantees that |QR| ≤ |PR|. Thus, we do not need to consider PR when building the spanning tree.

Octants

This reduces the problem to that of finding the nearest neighbour in each octant. We'll just consider the octant shown; the others are no different and can be handled by symmetry. It should be clear that within this octant, finding the nearest neighbour is equivalent to just finding the point with the largest value of x − y, subject to an upper bound on x + y and a lower bound on y, and this is the form in which we'll consider the problem.

Now imagine for the moment that the lower bound on y did not exist. In this case we could solve the problem for every P quite easily: sweep through the points in increasing order of x + y, and Q will be the point with the largest x − y value of those seen so far. This is where the divide-and-conquer principle comes into play: we partition the point set into two halves with a horizontal line, and recursively solve the problem for each half. For points P in the upper half, nothing further needs to be done, because points in the bottom half cannot play Q to their P. For the bottom half, we have to consider that by ignoring the upper half so far we may have missed some closer points. However, we can take these points into account in a similar manner as before: walk through all the points in x + y order, keeping track of the best point in the top half (largest x − y value), and for each point in the bottom half, checking whether this best top-half point is better than the current neighbour.

So far I have blithely assumed that any set of points can be efficiently partitioned on Y and also walked in x + y order without saying how this should be done. In fact, one of the most beautiful aspects of this class of divide-and-conquer plus line-sweep algorithms is that it has essentially the same structure as a merge sort, to the point that a merge-sort by x + y can be folded into the algorithm in such a way that each subset is sorted on x + y just when this is needed (the points initially all being sorted on Y). This gives the algorithm a running time of O(N log N).

The idea of finding the closest point within an angle range can also be used to solve the Euclidean MST problem, but the O(N log N) running time is no longer guaranteed in the worst cases, because the distance is no longer a linear equation. It is actually possible to compute the Euclidean MST in O(N log N) time, because it is a subset of the Delaunay triangulation.

[Dr.Lib]Note:Data Structures – Bottom-up SPLAY

Let us play!

Let u splay!

 

BST 平均 O(logn)

Treap 期望 O(logn)

Splay 均摊 O(logn)

AVL 严格 O(logn)

SBT 严格 O(logn)

AVL不大指望能在赛场写出来,SBT在绝大多数时候是个不错的选择,Treap…嗯……但偏偏Splay被人看成是BST中的万金油……为什么呐?

Splay一个最大的特点就是:每一个操作都要splay一下……除此之外没了……

Splay

splay操作的作用就是把某一节点旋转到根,以加快之后的访问速度。它还可以在旋转过程中维持树的基本平衡。

  1. zig: 当目标节点是根节点的 左子节点 或 右子节点 时,进行一次zig,将目标节点调整到根节点的位置。
    709px-Splay_tree_zig.svg
  2. zig-zig:当目标节点是根节点的 左(右)子节点的左(右)子节点 时,进行一次zig-zig,将目标节点调整到根节点位置。
    Zigzig
  3. zig-zag:当目标节点是根节点的 左(右)子节点的右(左)子节点 时,进行一次zig-zag,将目标节点调整到根节点位置。
    Zigzag

 

重复这几种操作直到目标节点为根。

一次zig、zig-zig、zig-zag又可以分解为几次单旋。

Search/Insert/Rank/Select

与BST相同,只不过记得把插入的节点Splay到根。

Join

作用是把两棵子树S1,S2连成一个Splay,其中S1中所有元素小于S2。

先找到S1中的最大节点x,Splay到S1的根,再把x的右子树链接到S2。

Delete

先找到目标节点,Splay到根,执行Join操作即可。

代码

 

 

 

[Dr.Lib]Note:Algorithm – SSSP

最短路是图论中的基础,单源最短路SSSP是基础的基础(2333自己发明的名言……

关于图论算法之前只说了存图……唔今天先复习一下SSSP的几个算法。

Dijkstra

 SPFA

SPFA不仅是SSSP的一个算法,而更多的是一种思想。

国家集训队2009论文集SPFA算法的优化及应用

[Dr.Lib]Note:Data Structures – Size Balanced Tree – II

。。也没什么好说的了,《Size Balanced Tree》(CQF WC 2006)说的很清楚了……

今晚(昨晚?手敲的代码……不知道如何……