Stretch tree (reprint http://acm.tju.edu.cn/blog? P = 85)

Source: Internet
Author: User

I wrote treap and left Tree some days ago. I have read about the stretch tree in the past two days. I will write it here for your reference.

 

The left-side tree is a diagonal heap, while the treap is a mixture of tree and heap, that is, a heap and a binary search tree. It is suitable for playing games with a small amount of code and easy debugging. But for some problems, such as complicated operations, the above data structure may not be fixed, so we can try it with splay.

 

As a feature of a binary sorting tree, splay is described in this article as "you can place the indicated node in the root of the tree or as the son of the root of the tree ". it is a self-adjusting tree, move the recently accessed node to the root so that it can be quickly found the next time you access it. I understand that splay only has one operation: Move a node to the root, in this process, we do not need to deal with the balance problem. Although it may become a linear shape, it is a small probability event.

 

As far as my current knowledge is concerned, splay is powerful in its ability to quickly perform operations on intervals, for example, a sequence's indicated stator sequence is reversed or they are moved to a new position as a whole (refer to the TOJ-3578 ).. You can also insert, delete, and update elements at random at the specified position of the interval, at the same time, we can quickly obtain the sum of the specified stator interval and the maximum and minimum values of the specified consecutive or interval (refer to the SPOJ-4487)

 

It seems that the maximum and minimum values of the query interval and the subinterval and the maximum consecutive values are not the same as those of the line trunk. Yes, you did not think wrong. Before learning splay, the line segment tree is indeed a master who handles this interval problem. However, after you have mastered splay completely, it allows you to process more interval operations, for some problems, its internal strength is much higher than that of the Line Segment tree. For some complicated problems, it is not necessary to use it.

 

Now let's talk about the charm of the Binary Tree: If you already know the Left and Right rotation operations of the binary tree, you can certainly

Rotate a specified node in the tree to the root. This is the housekeeping skill of splay. Other extension functions depend on it. First, let's talk about how to insert a value at a specified position, assuming a splay tree with Series 1, 2, 3, 4, 5, 6, and 7 as elements, if we want to insert a new element with the value of val between the First and Fourth positions (namely, 3 and 4), we should perform the following operations:

(1) rotate element 3 to the root.

(2) rotate element 4 under the root node as the son of 3.

In this case, 4 must be the right son of 3, and its left son is empty, now, create a new element with the val value and place it on the left child of the right child of the root (do not understand it ). If the splay tree is first traversed, does it find that val is already between 3 and 4.

 

In the same way, you can insert a new area to a specified location or delete a specified value and specified range, the method is to rotate two elements or intervals to be processed, and then the magic process is now at the left of the right child of the root, if there are other statistical information that can be recorded at the root of the corresponding interval, pay attention to real-time update when the splay operation rotates it.

 

If you are interested, write these two questions.

 

Https://www.spoj.pl/problems/GSS6/

 

Http://acm.tju.edu.cn/toj/showp3578.html

 

The following is the spoj 4487 code, which can be used as a template.

 

# Include <iostream>

# Include <cstring>

# Include <algorithm>

# Include <vector>

# Include <cmath>

# Include <string>

# Include <map>

# Include <fstream>

Using namespace STD;

Typedef long ll;

 

Const int maxn = 102000*2;

Const int INF = (1 <28 );

 

Int ary [maxn];

Struct node {

Int Val, SZ;

Int sum, ML, Mr, MC;

Node * Ch [2], * pre;

};

Class splay {

Public:

Node * null, * root, * s [maxn], data [maxn];

Int CNT, top;

Node * getnewnode (int x ){

Node * P;

If (top ){

P = s [top --];

} Else {

P = & Data [CNT ++];

}

P-> val = p-> sum = p-> ML = p-> mr = p-> MC = x;

P-> SZ = 1;

P-> CH [0] = p-> CH [1] = p-> pre = NULL;

Return P;

}

Void Init (){

CNT = Top = 0;

Null = getnewnode (-INF );

Null-> sum = NULL-> SZ = 0;

Root = getnewnode (-INF );

Root-> sum = 0;

Root-> ch [1] = getNewNode (INF );

Root-> ch [1]-> sum = 0;

Root-> ch [1]-> pre = root;

Updata (root );

}

Void updata (Node * p ){

P-> sz = p-> ch [0]-> sz + p-> ch [1]-> sz + 1;

P-> sum = p-> ch [0]-> sum + p-> ch [1]-> sum + p-> val;

// How is this thing like a line segment tree!

P-> ml = max (p-> ch [0]-> ml, p-> ch [0]-> sum + p-> val + max (p-> ch [1]-> ml, 0 ));

P-> mr = max (p-> CH [1]-> Mr, p-> CH [1]-> sum + P-> Val + max (p-> CH [0]-> Mr, 0 ));

// The continuous maximum value on the left of ML, the continuous maximum value on the Right of Mr, and the continuous maximum value on the MC point as the root

P-> MC = max (p-> CH [0]-> MC, p-> CH [1]-> MC );

P-> MC = max (p-> MC, max (p-> CH [0]-> MR + P-> CH [1]-> ML, 0) + P-> Val );

P-> MC = max (p-> MC, max (p-> CH [0]-> Mr, p-> CH [1]-> ML) + P-> Val );

}

Void rotate (node * X, int c ){

// C = 1 indicates that the right hand 0 indicates the left hand, And the x node is rotated to its parent position.

Node * Y = x-> pre;

Y-> CH [! C] = x-> CH [c];

If (X-> CH [c]! = NULL ){

X-> ch [c]-> pre = y;

}

X-> pre = y-> pre;

If (y-> pre! = Null ){

If (y-> pre-> ch [0] = y ){

Y-> pre-> ch [0] = x;

} Else {

Y-> pre-> ch [1] = x;

}

}

X-> ch [c] = y;

Y-> pre = x;

If (y = root ){

Root = x;

}

Updata (y );

}

Void splay (Node * x, Node * f ){

// Rotate node x to the son of f. If f is null, x is rotated to the root position.

While (x-> pre! = F ){

If (x-> pre = f) {// zig

Rotate (x, x-> pre-> ch [0] = x );

/* If (x-> pre-> ch [0] = x ){

Rotate (x, 1); // right-hand

} Else {

Rotate (x, 0); // left-hand

} * // <=> Rotate (x, x-> pre-> ch [0] = x );

} Else {

Node * y = x-> pre;

Node * z = y-> pre;

If (z-> ch [0] = y ){

If (y-> ch [0] = x ){

Rotate (y, 1), rotate (x, 1); // zig-zig

} Else {

Rotate (x, 0), rotate (x, 1); // zig-zag

}//

} Else {

If (Y-> CH [1] = x ){

Rotate (Y, 0), rotate (x, 0); // zig-Zig

} Else {

Rotate (x, 1), rotate (x, 0); // zig-zag

}

}

}

}

Updata (x );

}

Void select (int kth, Node * f ){

// Locate the k element and rotate it to become the son of f

Int tmp;

Node * t = root;

While (true ){

Tmp = t-> ch [0]-> sz;

If (tmp + 1 = kth) {// find the right one

Break;

}

If (KTH <= TMP ){

T = T-> CH [0];

} Else {

Kth-= TMP + 1;

T = T-> CH [1];

}

}

Splay (T, F );

}

Void insert (INT POs, int Val ){

// Insert a node before the POs

Node * tmproot = getnewnode (VAL );

Select (POS-1, null );

Select (pos, root );

Root-> ch [1]-> ch [0] = tmproot;

Tmproot-> pre = root-> ch [1];

Splay (root-> ch [1], null );

}

Void del (int k ){

// Delete the k-th element. k cannot be 1;

Select (k, null );

Node * old_root = root;

Root = root-> ch [1];

Root-> pre = null;

Select (1, null );

Root-> ch [0] = old_root-> ch [0];

Root-> ch [0]-> pre = root;

Updata (root );

S [++ top] = old_root;

}

Void replace (int x, int y ){

// Replace the element value at position x with y

Select (x, null );

Root-> val = y;

Updata (root );

}

Node * build (int l, int r ){

// Isn't this the process of building a line segment tree?

If (l> r ){

Return null;

}

Int m = (l + r)> 1;

Node * p = getNewNode (ary [m]);

P-> ch [0] = build (l, m-1 );

If (p-> ch [0]! = Null ){

P-> ch [0]-> pre = p;

}

P-> ch [1] = build (m + 1, r );

If (p-> ch [1]! = Null ){

P-> ch [1]-> pre = p;

}

Updata (p );

Return p;

}

};

 

Splay sp;

 

Int main ()

{

Int n, m, I, X, Y;

Char C;

Sp. INIT ();

Scanf ("% d", & N );

For (INT I = 1; I <= N; ++ I ){

Scanf ("% d", & ary [I]);

}

 

Node * troot = sp. Build (1, N );

Sp. Root-> CH [1]-> CH [0] = troot;

Troot-> pre = sp. Root-> CH [1];

Sp. updata (sp. Root-> CH [1]);

Sp. updata (sp. Root );

Sp. splay (sp. Root-> CH [1], sp. null );

Scanf ("% d", & M );

For (int I = 1; I <= m; ++ I ){

Scanf ("% c", & c );

If (c = 'I '){

Scanf ("% d", & x, & y );

Sp. insert (++ x, y );

} Else if (c = 'D '){

Scanf ("% d", & x );

Sp. del (++ x );

} Else if (c = 'R '){

Scanf ("% d", & x, & y );

Sp. replace (++ x, y );

} Else if (c = 'q '){

Scanf ("% d", & x, & y );

Sp. select (++ x-1, sp. null );

Sp. select (++ y + 1, sp. root );

Printf ("% d/n", sp. root-> ch [1]-> ch [0]-> mc );

}

}

Return 0;

}

 

Reproduced in: http://acm.tju.edu.cn/blog? P = 85

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.