输出:1个字母‘I‘,紧接着1个数字k,表示插入一个数字k到树中,保证每个k都不相同。
1个字母‘Q‘,紧接着1个数字k。表示询问树中不超过k的最大数字;
1个字母‘D‘,紧接着2个数字a,b,表示删除树中在区间[a,b]的数。
程序代码:
/****************************************************/ /* File : Hiho_Week_103 */ /* Author : Zhang Yufei */ /* Date : 2016-07-09 */ /* Description : HihoCoder ACM program. (submit:g++)*/ /****************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> /* * Define the node in splay tree. * Parameters: * @value: The value of this node. * @max: The max value in the sub-tree. * @tag: Mark if the node is real or fake. * @left & @right: The left and right child. * @parent: The parent node of this node. */ typedef struct node { int value; int max; int tag; struct node *left, *right; struct node *parent; } node; // The root of splay tree. node* root; /* * This function define the left rotate operation. * Parameters: * @cur: The current node to rotate. * Returns: * None. */ void left_rotate(node* cur) { node* right = cur->right; node* right_left = right->left; node* parent = cur->parent; right->parent = cur->parent; if(parent != NULL) { if(cur == parent->left) { parent->left = right; } else { parent->right = right; } } else { root = right; } right->left = cur; cur->parent = right; cur->right = right_left; if(right_left != NULL) { right_left->parent = cur; } if(cur->tag == 1) { cur->max = cur->value; } else { cur->max = 0; } if(cur->left != NULL) { if(cur->left->max > cur->max) { cur->max = cur->left->max; } } if(cur->right != NULL) { if(cur->right->max > cur->max) { cur->max = cur->right->max; } } if(right->tag == 1) { right->max = right->value; } else { right->max = 0; } if(right->left != NULL) { if(right->left->max > right->max) { right->max = right->left->max; } } if(right->right != NULL) { if(right->right->max > right->max) { right->max = right->right->max; } } } /* * This function define the right rotate operation. * Parameters: * @cur: The current node to rotate. * Returns: * None. */ void right_rotate(node* cur) { node* left = cur->left; node* left_right = left->right; node* parent = cur->parent; left->parent = cur->parent; if(parent != NULL) { if(cur == parent->left) { parent->left = left; } else { parent->right = left; } } else { root = left; } left->right = cur; cur->parent = left; cur->left = left_right; if(left_right != NULL) { left_right->parent = cur; } if(cur->tag == 1) { cur->max = cur->value; } else { cur->max = 0; } if(cur->left != NULL) { if(cur->left->max > cur->max) { cur->max = cur->left->max; } } if(cur->right != NULL) { if(cur->right->max > cur->max) { cur->max = cur->right->max; } } if(left->tag == 1) { left->max = left->value; } else { left->max = 0; } if(left->left != NULL) { if(left->left->max > left->max) { left->max = left->left->max; } } if(left->right != NULL) { if(left->right->max > left->max) { left->max = left->right->max; } } } /* * This function define the zig operation. * Parameters: * @cur: The current node to operate. * Returns: * None. */ void zig(node* cur) { node* p = cur->parent; if(cur == p->left) { right_rotate(p); } else { left_rotate(p); } } /* * This function define the zig-zig operation. * Parameters: * @cur: The current node to operate. * Returns: * None. */ void zig_zig(node* cur) { node *p = cur->parent; node *pp = p->parent; if(cur == p->left) { right_rotate(pp); right_rotate(p); } else { left_rotate(pp); left_rotate(p); } } /* * This function define the zig-zag operation. * Parameters: * @cur: The current node to operate. * Returns: * None. */ void zig_zag(node* cur) { node *p = cur->parent; node *pp = p->parent; if(cur == p->left) { right_rotate(p); left_rotate(pp); } else { left_rotate(p); right_rotate(pp); } } /* * This function define the splay operation. * Parameters: * @cur: The current node to operate. * @dst: The destination node. * It's the parent node of @cur in final state. * Returns: * None. */ void splay(node* cur, node* dst) { while(cur->parent != dst) { node *p = cur->parent; if(p->parent == dst) { zig(cur); } else { node* pp = p->parent; if(cur == p->left && p == pp->left || cur == p->right && p == pp->right) { zig_zig(cur); } else { zig_zag(cur); } } } } /* * This function find the preview node of the current node. * Parameters: * @cur: The current node to search. * Returns: * The preview node of the current node. */ node* preview(node* cur) { node* pre = cur->left; if(pre != NULL) { while(pre->right != NULL) { pre = pre->right; } } else { pre = cur; while(pre != NULL) { if(pre->parent != NULL && pre == pre->parent->right) { pre = pre->parent; break; } pre = pre->parent; } } return pre; } /* * This function find the successor node of the current node. * Parameters: * @cur: The current node to search. * Returns: * The successor node. */ node* successor(node *cur) { node *suc = cur->right; if(suc != NULL) { while(suc->left != NULL) { suc = suc->left; } } else { suc = cur; while(suc != NULL) { if(suc->parent != NULL && suc == suc->parent->left) { suc = suc->parent; break; } suc = suc->parent; } } return suc; } /* * This function insert a node into the splay tree. * Parameters: * @ins: The node to insert. * Returns: * The inserted node. */ node* insert(node* ins) { node* p = root; node* pre = NULL; while(p != NULL) { pre = p; if(ins->tag == 1) { if(p->max < ins->value) { p->max = ins->value; } } if(ins->value > p->value) { p = p->right; } else if(ins->value < p->value) { p = p->left; } else { if(ins->tag == 1) { p->value = ins->value; p->max = p->value; p->tag = 1; } splay(p, NULL); free(ins); ins = p; return ins; } } if(pre != NULL) { if(pre->value > ins->value) { pre->left = ins; } else { pre->right = ins; } ins->parent = pre; } else { root = ins; } splay(ins, NULL); return ins; } /* * This function search the node according to the given range. * Parameters: * @s & @e: The left and right edge of range. * Returns: * The root of the sub-tree which contains nodes in the * given range. */ node* search(int s, int e) { node* s_node = (node*) malloc(sizeof(node)); s_node->value = s; s_node->max = 0; s_node->tag = 0; s_node->left = s_node->right = s_node->parent = NULL; node* e_node = (node*) malloc(sizeof(node)); e_node->value = e; e_node->max = 0; e_node->tag = 0; e_node->left = e_node->right = e_node->parent = NULL; s_node = insert(s_node); e_node = insert(e_node); node* s_pre = preview(s_node); node* e_next = successor(e_node); splay(s_pre, NULL); splay(e_next, s_pre); return e_next->left; } /* * This function delete the nodes according to given range. * Parameters: * @s & @e: The left and right edge of range. * Returns: * None. */ void remove(int s, int e) { node *del = search(s, e); if(del != NULL) { node* p = del->parent; if(p != NULL) { if(p->left == del) { p->left = NULL; } else { p->right = NULL; } } else { root = NULL; } while(p != NULL) { if(p->tag == 1) { p->max = p->value; } else { p->max = 0; } if(p->left != NULL) { if(p->max < p->left->max) { p->max = p->left->max; } } if(p->right != NULL) { if(p->max < p->right->max) { p->max = p->right->max; } } p = p->parent; } } } /* * The main program. */ int main(void) { int n; scanf("%d", &n); node* min = (node*) malloc(sizeof(node)); min->value = 0; min->max = 0; min->tag = 0; min->left = min->right = min->parent = NULL; node* max = (node*) malloc(sizeof(node)); max->value = 1000000001; max->max = 0; max->tag = 0; max->left = max->right = max->parent = NULL; insert(min); insert(max); for(int i = 0; i < n; i++) { char op; getchar(); scanf("%c", &op); if(op == 'I') { int k; scanf("%d", &k); node *ins = (node*) malloc(sizeof(node)); ins->value = k; ins->max = k; ins->tag = 1; ins->left = ins->right = ins->parent = NULL; insert(ins); } else if(op == 'Q') { int k; scanf("%d", &k); node* r = search(1, k); printf("%d\n", r->max); } else if(op == 'D') { int a, b; scanf("%d %d", &a, &b); a = a > 1 ? a : 1; b = b < 1000000000 ? b : 1000000000; remove(a, b); } } return 0; }
原文:http://blog.csdn.net/octopusflying/article/details/51888826