zoukankan      html  css  js  c++  java
  • poj_1442 Treap

    Treap是一种动态平衡二叉树结构,具有期望的O(log2n)的复杂度。适用于动态区间数据的查询、更改、维护等操作。

    题目大意

        一组数从前向后插入队列中,插入的过程中会有查询,查询当前队列中的第k小的数。

    题目分析

        对于数据的查询,可以考虑使用treap这种平衡二叉树来实现。而且treap这种动态平衡树结构,可以很方便的实现第k大的查询。 
        需要注意的是,每个节点保存与该节点相同元素的个数count对查询第k个数据时候的影响,见代码。

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<algorithm>
    #define MAX_NUM 30010
    struct TreapNode{
    	int key;
    	int priority;
    	int size;
    	int count;
    	TreapNode* child[2];
    	TreapNode(int val){
    		key = val;
    		priority = rand();
    		child[0] = child[1] = NULL;
    		count = size = 1;
    	}
    	void Update(){
    		size = count;
    		if (child[0]){
    			size += child[0]->size;
    		}
    		if (child[1]){
    			size += child[1]->size;
    		}
    	}
    };
    
    struct Treap{
    	TreapNode* root;
    	Treap() :root(NULL){};
    	void Rotate(TreapNode*& node, int dir){
    		TreapNode* ch = node->child[dir];
    		node->child[dir] = ch->child[!dir];
    		ch->child[!dir] = node;
    
    		node->Update();
    		node = ch; //reference
    	}
    	void Insert(TreapNode*& node, int k){
    		if (!node){
    			node = new TreapNode(k);
    		}
    		else if (node->key == k){
    			node->count++;
    		}
    		else{
    			int dir = node->key < k;
    			Insert(node->child[dir], k);
    			if (node->priority < node->child[dir]->priority){
    				Rotate(node, dir);
    			}
    		}
    		node->Update();
    	}
    	int GetKth(TreapNode* root, int k){
    		TreapNode* node = root;
    		while (node){
    			if (!node->child[0]){
    				if (k <= node->count){
    					return node->key;
    				}
    				else{
    					k -= (node->count);
    					node = node->child[1];
    				}
    			}
    			else{
    				if (node->child[0]->size < k && node->child[0]->size + node->count >= k){
    					return node->key;
    				}
    				else if (node->child[0]->size >= k){
    					node = node->child[0];
    				}
    				else{
    					k -= (node->child[0]->size + node->count);
    					node = node->child[1];
    					
    				}
    			}
    		}
    		return 0;
    	}
    };
    int gNumber[MAX_NUM];
    Treap gTreap;
    int main(){
    	int number_count, query_count;
    	scanf("%d%d", &number_count, &query_count);
    	for (int i = 0; i < number_count; i++){
    		scanf("%d", &gNumber[i]);
    	}
    
    	int query_old = 0;
    	int query_new;
    	for (int i = 1; i <= query_count; i++){
    		scanf("%d", &query_new);
    		for (int k = query_old; k < query_new; k++){
    			gTreap.Insert(gTreap.root, gNumber[k]);
    		}
    		query_old = query_new;
    		int result = gTreap.GetKth(gTreap.root, i);
    		printf("%d
    ", result);
    	}
    	return 0;
    }
    
  • 相关阅读:
    第四章作业
    第二章上机实验报告
    对二分法的理解和结对编程情况
    Mysql与sql server的列的合并
    C#中如何去除窗体默认的关闭按钮
    C# 实现WinForm窗口最小化到系统托盘代码,并且判断左右鼠标的事件
    running total sql 2012+
    Poqwe Pivot error
    事务
    ssis 导EXCEL ERROR
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4717617.html
Copyright © 2011-2022 走看看