标签:
输出: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