Reprinted please indicate the source, thank youHttp://blog.csdn.net/ACM_cxlove? Viewmode = Contents
By --- cxlove
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
# 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 hhvoid treaval (int x) {If (X) {treaval (CH [x] [0]); printf ("Node % 2D: Left son % 2D right son % 2 D 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, in T 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) {// 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; elsehigh = 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]); // locate the smallest splay in the right child (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 to 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, it is worried that push_up (R) is always searched for in the left subtree;} void top (int x) {int K = Bin (X ); int y = node [k]; // locate the label splay (Y, 0) between the workers; // rotate it to the root if (! Ch [root] [0] |! Ch [root] [1]) {// The left and right children are incomplete. Directly pull the child to the root Root = CH [root] [0] + CH [root] [1]; pre [root] = 0;} elsedelete (); // Delete the node insert (root, K, 0); // Insert the 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; elsereturn 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]); elseprintf ("% d \ n", get_kth (root, OPE [I]);} int main () {int t, CAS = 0; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & Q ); // discretization all top and query operation vertices, reducing the inner range to 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 [Tota L ++] = N; sort (p, p + total); CNT = 0; // discretization; s [I] indicates the start point of the interval, E [I] indicates the end of the interval for (INT I = 1; I <total; I ++) if (P [I]! = P [I-1]) {If (P [I]-P [I-1]> 1) {// The middle interval 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 ;}