输出: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
#include
#include
/*
* 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;
}