HDU 3436 Queue-jumpers (Splay tree)

Source: Internet
Author: User

Three operations are RANK, TOP, and QUERY. Nima, N ranges from 10 to 8 and must be discretization.
Three operations are analyzed carefully:
RANK is used to find the number of the K-bit.
TOP is to move a person to the front of the team, which has no impact on the middle Interval
QUERY is the location of a person.
It can be found that the QUERY and TOP operations are separated, and the other intervals in the middle need to be reduced. You only need to save the Interval Length to facilitate the subsequent ranking statistics.
For the scaled-down interval, the operation is ordered internally, and the order is not changed. During statistics, you only need to find the interval by ranking and starting point. For QUERY operations, you can also separate the operation points.
After discretization, it is the basic operation of Splay.
TOP: rotate the target point to the root, delete it, and insert it to the beginning of the team.
RANK: search by size. Note that the size of each vertex is the interval length.
QUERY: rotate the vertex to the root. The result is the size of the Left subtree plus 1.
The rotation of Splay is amazing, Orz
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <cstdio>
# Include <algorithm>
# Define N 100015
# Define inf 1 <29
# Define LL long
# Define Key_value ch [ch [root] [1] [0]
Using namespace std;
Int n, q, p [N], cnt, s [2 * N], e [2 * N], ope [N];
Int node [2 * N];
Char str [N] [10];
Int root, tot, size [2 * N], key [2 * N], pre [2 * N], ch [2 * N] [2], num [2 * N];
// Debug part COPY from HH
Void Treaval (int x ){
If (x ){
Treaval (ch [x] [0]);
Printf ("Node % 2d: Left son % 2d right son % 2d parent node % 2d size = % 2d, key = % 2d num = % 2d \ n", x, ch [x] [0], ch [x] [1], pre [x], size [x], key [x], num [x]);
Treaval (ch [x] [1]);
}
}
Void debug () {printf ("% d \ n", root); Treaval (root );}
Void Push_Up (int r ){
Size [r] = size [ch [r] [0] + size [ch [r] [1] + num [r];
}
Void NewNode (int & r, int father, int k ){
R = ++ tot;
Pre [r] = father;
Size [r] = e [k]-s [k] + 1;
Num [r] = e [k]-s [k] + 1;
Key [r] = k;
Node [k] = r;
Ch [r] [0] = ch [r] [1] = 0;
}
Void Bulid (int & x, int l, int r, int father ){
If (l> r)
Return;
Int mid = (l + r)/2;
NewNode (x, father, mid );
Bulid (ch [x] [0], l, mid-1, x );
Bulid (ch [x] [1], mid + 1, r, x );
Push_Up (x );
}
Void Rotate (int x, int kind ){
Int y = pre [x];
Ch [y] [! Kind] = ch [x] [kind];
Pre [ch [x] [kind] = y;
If (pre [y])
Ch [pre [y] [ch [pre [y] [1] = y] = x;
Pre [x] = pre [y];
Ch [x] [kind] = y;
Pre [y] = x;
Push_Up (y );
}
Void Splay (int r, int goal ){
While (pre [r]! = Goal ){
If (pre [pre [r] = goal)
Rotate (r, ch [pre [r] [0] = r );
Else {
Int y = pre [r];
Int kind = (ch [pre [y] [0] = y );
If (ch [y] [kind] = r ){
Rotate (r ,! Kind );
Rotate (r, kind );
}
Else {
Rotate (y, kind );
Rotate (r, kind );
}
}
}
Push_Up (r );
If (goal = 0) root = r;
}
Int Bin (int x) {// In discretization, binary search
Int low = 0, high = cnt-1, mid;
While (low <= high ){
Mid = (low + high)> 1;
If (s [mid] <= x & e [mid]> = x)
Return mid;
If (e [mid] <x)
Low = mid + 1;
Else
High = mid-1;
}
}
Int Get_Min (int r ){
Push_Up (r );
While (ch [r] [0]) {
R = ch [r] [0];
Push_Up (r );
}
Return r;
}
Void Delete (){
Int k = Get_Min (ch [root] [1]); // find the smallest of the right children
Splay (k, root); // rotate to make the right subtree have no left child
Ch [ch [root] [1] [0] = ch [root] [0]; // give the original left child to the right subtree as the left child
Root = ch [root] [1]; // set the right child as the root
Pre [ch [root] [0] = root;
Pre [root] = 0;
Push_Up (root );
}
Void Insert (int & r, int k, int father ){
If (r = 0 ){
NewNode (r, father, k );
Return;
}
Insert (ch [r] [0], k, r); // because it is inserted to the head of the team, I am worried that I will keep searching for the left subtree.
Push_Up (r );
}
Void Top (int x ){
Int k = Bin (x );
Int y = node [k]; // locate the inter-zone label of the person
Splay (y, 0); // rotate to the root
If (! Ch [root] [0] |! Ch [root] [1]) {// The left and right children are incomplete, and the children are directly pulled to the root
Root = ch [root] [0] + ch [root] [1];
Pre [root] = 0;
}
Else
Delete (); // Delete a node
Insert (root, k, 0); // Insert again
Splay (tot, 0); // rotate to the root, this step does not add TLE
}
Int Get_Rank (int x ){
Int k = Bin (x );
Int y = node [k];
Splay (y, 0 );
Return size [ch [root] [0] + 1;
}
Int Get_Kth (int r, int k ){
Int t = size [ch [r] [0];
If (k <= t)
Return Get_Kth (ch [r] [0], k );
Else if (k <= t + num [r])
Return s [key [r] + (k-t)-1;
Else
Return Get_Kth (ch [r] [1], k-t-num [r]);
}
Void slove (){
For (int I = 0; I <q; I ++ ){
If (str [I] [0] = 'T ')
Top (ope [I]);
Else if (str [I] [0] = 'q ')
Printf ("% d \ n", Get_Rank (ope [I]);
Else
Printf ("% d \ n", Get_Kth (root, ope [I]);
}
} Www.2cto.com
Int main (){
Int t, cas = 0;
Scanf ("% d", & t );
While (t --){
Scanf ("% d", & n, & q );
// Discretization all TOP and QUERY operation vertices, reducing the unchanged center intervals to vertices
Int total = 0;
P [total ++] = 0;
For (int I = 0; I <q; I ++ ){
Scanf ("% s % d", str [I], & ope [I]);
If (str [I] [0] = 'T' | str [I] [0] = 'q ')
P [total ++] = ope [I];
}
P [total ++] = n;
Sort (p, p + total );
Cnt = 0;
// Discretization. s [I] indicates the start point of the interval, and e [I] indicates the end point of the interval.
For (int I = 1; I <total; I ++)
If (p [I]! = P [I-1]) {
If (p [I]-p [I-1]> 1) {// The interval in the middle
S [cnt] = p [I-1] + 1;
E [cnt] = p [I]-1;
Cnt ++;
}
S [cnt] = p [I]; // endpoint
E [cnt] = p [I];
Cnt ++;
}
Root = tot = 0;
Ch [root] [0] = ch [root] [1] = pre [root] = size [root] = num [root] = key [root] = 0;
Bulid (root, 0, cnt-1, 0); // build
Printf ("Case % d: \ n", ++ cas );
Slove ();
}
Return 0;
}

 


By ACM_cxlove

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.