zoukankan      html  css  js  c++  java
  • HDU 4585 ShaoLin 基础Treap

    这题其实就是一个在二叉搜索树里面找前驱和后继的题,以前好像用线段树+离散化搞过,弄得比较挫,学会AVL了之后就是方便。

    简单说一下怎么找前驱和后继,

    前驱的话,如果当前节点有左子树,那么前驱就是左子树中的最大节点,否则往上找第一个是他父亲节点的右儿子的节点,后继和前驱差不多,反过来就行。

    因为我这里没有存parent指针,如果存的话旋转起来比较麻烦,所以我是先从根找到这个节点,沿途记录了一下。

    #include <cstdio>
    #include <climits>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    
    const int maxn = 2e5 + 10;
    
    struct Node {
    	Node *ch[2];
    	int rkey, val, size, id;
    	Node(int val, int id): val(val), id(id) {
    		ch[0] = ch[1] = NULL;
    		rkey = rand();
    		size = 1;
    	}
    	void maintain() {
    		size = 1;
    		if(ch[1] != NULL) size += ch[1]->size;
    		if(ch[0] != NULL) size += ch[0]->size;
    	}
    };
    
    void rotate(Node *&o, int d) {
    	Node *k = o->ch[d ^ 1];
    	o->ch[d ^ 1] = k->ch[d];
    	k->ch[d] = o;
    	o->maintain(); k->maintain();
    	o = k;
    }
    
    void insert(Node *&o, int x, int id) {
    	if(o == NULL) o = new Node(x, id);
    	else {
    		int d = x > o->val;
    		insert(o->ch[d], x, id);
    		if(o->ch[d]->rkey > o->rkey) 
    			rotate(o, d ^ 1);
    	}
    	o->maintain();
    }
    
    void remove_tree(Node *&o) {
    	if(o == NULL) return;
    	if(o->ch[0] != NULL) remove_tree(o->ch[0]);
    	if(o->ch[1] != NULL) remove_tree(o->ch[1]);
    	delete(o); o = NULL;
    }
    
    Node* query(Node *o, int x, int dx) {
    	//dx = 0
    	Node *pre = NULL;
    	while(o != NULL && o->val != x) {
    		int d = x > o->val;
    		if(d == dx ^ 1) pre = o;
    		o = o->ch[d];
    	}
    	o = o->ch[dx];
    	if(o == NULL) return pre;
    	else {
    		while(o->ch[dx ^ 1] != NULL) 
    			o = o->ch[dx ^ 1];
    		return o;
    	}
    }
    
    int calc(Node *r, int k) {
    	if(r == NULL) return INT_MAX;
    	return abs(r->val - k);
    }
    
    Node *root;
    int n;
    
    int main() {
    	while(scanf("%d", &n), n != 0) {
    		remove_tree(root);
    		insert(root, 1e9, 1);
    		for(int i = 1; i <= n; i++) {
    			int id, k, ans; 
    			scanf("%d%d", &id, &k);
    			insert(root, k, id);
    			Node *r0 = query(root, k, 0), 
    				*r1 = query(root, k, 1);
    			int d0 = calc(r0, k), d1 = calc(r1, k);
    			if(d0 > d1) ans = r1->id;
    			else ans = r0->id;
    			printf("%d %d
    ", id, ans);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Python全栈开发——装饰器
    Python全栈开发——类
    Python全栈开发——Json & pickle & shelve & sys模块
    Python全栈开发——正则表达式
    实验3- 熟悉常用的 HBase 操作
    Hbase PleaseHoldException错误
    HDFS 中文件操作的错误集锦
    ubuntu在虚拟机下的安装 ~~~ Hadoop的安装及配置 ~~~ Hdfs中eclipse的安装
    假期周进度报告---08
    假期周进度报告---07
  • 原文地址:https://www.cnblogs.com/rolight/p/4276685.html
Copyright © 2011-2022 走看看