Data Structure Spaly_Tree

Source: Internet
Author: User

[Cpp]/********************************** * ***** data structure: splay_Tree: Stretch tree; nature: the extension tree is an improvement of the Binary Search Tree. Like the Binary Search Tree, the extension tree is also ordered. That is, each node x in the extension tree meets the following requirements: each element in the left subtree of the node is smaller than x, and each element in the right subtree is greater than x. Unlike the common binary lookup tree, the stretch tree can be adjusted by itself. features: A stretch tree is not a strictly balanced tree; it is also very likely to degrade to a linear structure, but a stretch operation can make every operation approximate (logn); a stretch operation: the stretching operation is similar to the balancing tree, except that he does not need to maintain a balance, but only the corresponding rotation. There are three situations for rotation: (1) zig or Zag (node x's parent node y is the root node) (2) Zig-Zig or Zag-Zag (node x's parent node y is not the root node, and x and y are both the left children of their parent nodes or the right children of their parent nodes) (3) zig-Zag or Zag-Zig (node x's parent node y is not the root node, one of x and y is the left child of its parent node, and the other is the right child of its parent node) one-font rotation and One-font rotation; advantage: it can quickly locate an interval [l, r] and delete or rotate the interval; rotate L-1 to the root (previous Splay operation) and node r + 1 to the right child of the root. Because of the nature of the stretch tree, it is still a binary search tree, you can know the nature of the binary search tree. The left subtree of the right child of the root node between the two nodes contains the node [l, r]. that is, the interval [l, r] was quickly located. to delete the interval, take the subtree directly. algorithm test: PKU3468 (A Simple Problem with Integers) Question: Q a B: the sum of the query intervals [a, B]; C a B x: update the range [a, B]. Add x to all values in the range; **************************************** * **/# include # Include # Include # IncludeUsing namespace std; # define Key_value ch [ch [root] [1] [0] // range of operations const int INF = 0 xffffff; const int N = 100010; typedef long LL; int ch [N] [2]; // left and right children (0 is left and 1 is right) int pre [N]; // parent node int key [N]; // data field int size [N]; // tree size int val [N]; int add [N]; int a [N]; // node element LL sum [N]; // subtree node and int root; // root node int tot; // number of nodes int n, q; void Push_Up (int u) // update the parent node {size [u] = size [ch [u] [0] + size [ch [u] [1] + 1 through the child node; sum [u] = sum [ch [u] [0] + sum [ch [u] [1] + val [u] + add [u];} void Push_Down (int u) // update the latency tag to the child node {if (add [u]) {val [u] + = add [u]; add [ch [u] [0] + = add [u]; add [ch [u] [1] + = add [u]; sum [ch [u] [0] + = (LL) add [u] * size [ch [u] [0]; sum [ch [u] [1] + = (LL) add [u] * size [ch [u] [1]; add [u] = 0 ;}} void New_Node (int & u, int f, int c) // create a node. f is the parent node {u = ++ tot; val [u] = sum [u] = c; pre [u] = f; size [u] = 1; ch [u] [1] = ch [u] [0] = add [u] = 0;} void Build_Tree (int & u, int l, int r, int f) // build a tree. The intermediate node is created first, and then {if (l> r) return; int m = (l + r)> 1 is created on both ends of the interval on the left and right subtree respectively; new_Node (u, f, a [m]); if (l Build_Tree (ch [u] [0], M-1, u); if (r> m) Build_Tree (ch [u] [1], m + 1, r, u); Push_Up (u);} void Rotate (int x, int c) // rotation operation, c = 0 indicates left-hand, c = 1 indicates the right-hand {int y = pre [x]; Push_Down (y); // first pass the mark of the Y node down (because Y is above) Push_Down (x ); // then pass the mark of X down ch [y] [! C] = ch [x] [c]; // similar to SBT, you must give a branch to the parent node pre [ch [x] [c] = y; pre [x] = pre [y]; if (pre [y]) // if the parent node is not the root node, connect to the parent node of the parent node {ch [pre [x] [ch [pre [y] [1] = y] = x ;} pre [y] = x; ch [x] [c] = y; Push_Up (y);} void Splay (int x, int f) // Splay operation, convert the root node x to {Push_Down (x); while (pre [x]! = F) {int y = pre [x]; if (pre [y] = f) // The Father of the parent node is f. Execute a single Rotate (x, ch [y] [0] = x); else {int z = pre [y]; int g = (ch [z] [0] = y ); if (ch [y] [g] = x) Rotate (x ,! G), Rotate (x, g); // Rotate else Rotate (y, g), Rotate (x, g ); // One-font rotation} Push_Up (x); // maintain the X node. if (f = 0) // update the root node {root = x ;}} void Rotate_Under (int k, int f) // stretch the number of the k-bit to the bottom of f {// locate the k-node traversal in the middle order, and rotate it to int p = root under Node f; // Push_Down (p) starting from the root node; // as the subnode to access p, the mark is passed down while (size [ch [p] [0]! = K) // the size of the Left subtree of p {if (k {P = ch [p] [0];} else // otherwise, in the right subtree, this node is no longer the k {k-= (size [ch [p] [0] + 1); p = ch [p] [1];} push_Down (p);} Splay (p, f); // execute rotation} int Insert (int k) // Insert node {int r = root; while (ch [r] [key [r] R = ch [r] [key [r] New_Node (ch [r] [k> key [r], r, k); // update the newly inserted node to the root node // Push_Up (r ); splay (ch [r] [k> key [r], 0); return 1;} int Get_Pre (int x) // find the precursor, that is, the rightmost node of the Left subtree {int tmp = ch [x] [0]; if (tmp = 0) return INF; while (ch [tmp] [1]) {tmp = ch [tmp] [1];} return key [x]-key [tmp];} int Get_Next (int x) // find the successor, that is, the leftmost node of the right subtree {int tmp = ch [x] [1]; if (tmp = 0) return INF; while (ch [tmp] [0]) {tmp = ch [tmp] [0];} return key [tmp]-key [x];} LL Query (int l, int r) // Query [l, r] And {Rotate_Under (L-1, 0); Rotate_Under (r + 1, root); return sum [Key_value];} void Update (int l, int r) // update {int k; scanf ("% d", & k); Rotate_Under (L-1, 0); Rotate_Under (r + 1, root ); add [Key_value] + = k; sum [Key_value] + = size [Key_value] * k;} void Init () // initialize {for (int I = 0; I Scanf ("% d", & a [I]); ch [0] [0] = ch [0] [1] = pre [0] = size [0] = 0; add [0] = sum [0] = 0; root = tot = 0; New_Node (root, 0,-1); New_Node (ch [root] [1], root,-1 ); // Add a vacancy size [root] = 2 to each header and tail; Build_Tree (Key_value, 0, n-1, ch [root] [1]); // put all data in the Push_Up (ch [root] [1]); Push_Up (root);} int main () {// freopen ("C: \ Users \ Administrator \ Desktop \ kd.txt "," r ", stdin); while (~ Scanf ("% d", & n, & q) {Init (); while (q --) {char op; scanf ("% c ", & op); int x, y; scanf ("% d", & x, & y); if (op = 'q ') printf ("% lld \ n", Query (x, y); else Update (x, y) ;}} return 0 ;}

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.