zoukankan      html  css  js  c++  java
  • poj_2352 Treap

    题目大意

        对于二维平面上的n个点,给出点的坐标。定义一个点A覆盖的点的个数为满足以下条件的点B的个数:点B的x <= 点A的x坐标,点B的y坐标 <= 点A的y坐标。 
        给出N个点的坐标,求出覆盖点的个数分别为0, 1, ... N-1 的点各有多少个。

    题目分析

        对于二维平面的点问题,可以考虑先进行行列排序,然后进行处理。对点进行排序(y从小到大,y相同,x从小到大)之后,按照y从小到大进行:单独考虑一行的点的x坐标,此时x坐标是升序的,因此当前点的肯定可以覆盖当前行中的之前访问的点;对于下方的点,它们的y坐标肯定小于当前点的y坐标,因此只考虑点的x坐标,如果x坐标小于等于当前点的x坐标,则点被当前点覆盖。 
        于是问题就化为了,按照从左下到右上的顺序遍历每个点的时候,比较该点和之前访问过的点的x坐标,统计之前点中x坐标小于等于当前点x坐标的个数 
        这就成了一个查找问题,查找问题可以考虑使用二查找树,于是可以使用treap这种平衡树。

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define MAX_NODE_NUM 15500
    struct TreapNode{
    	int key;
    	int priority;
    	int size;
    	int count;
    	TreapNode* child[2];
    	TreapNode(int val){
    		key = val;
    		child[0] = child[1] = NULL;
    		size = count = 1;
    		priority = rand();
    	}
    	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已经旋转到下方一层,因此size可能发生变化
    
    		node = ch;
    	}
    	
    	void Insert(TreapNode*& node, int key){
    		if (!node){
    			node = new TreapNode(key);
    		}
    		else if (node->key == key){
    			node->count++;
    		}
    		else {
    			int dir = node->key < key;
    			Insert(node->child[dir], key);
    			if (node->priority < node->child[dir]->priority){
    				Rotate(node, dir);
    			}
    		}
    		node->Update();
    	}
    	void debug(TreapNode* node){
    		if (node){
    			debug(node->child[0]);
    			printf("node's key = %d, priority = %d, count = %d, size = %d
    ", node->key, node->priority, node->count, node->size);
    			debug(node->child[1]);
    		}
    	}
    	
    	int GetLessK(TreapNode* node, int k){
    		int sum = 0;
    		if (!node){
    			return 0;
    		}
    		if (node->key > k){
    			sum += GetLessK(node->child[0], k);
    		}
    		else{
    			sum += node->count;
    			if (node->child[0]){
    				sum += node->child[0]->size;
    			}
    			sum += GetLessK(node->child[1], k);
    		}
    		return sum;
    	}
    };
    
    struct Point{
    	int x;
    	int y;
    };
    
    Point gPoints[MAX_NODE_NUM];
    
    Treap gTreap;
    int gCoverNum[MAX_NODE_NUM];
    int main(){
    
    	int N;
    	scanf("%d", &N);
    	for (int i = 0; i < N; i++){
    		scanf("%d %d", &gPoints[i].x, &gPoints[i].y);
    		gCoverNum[i] = 0;
    	}
    	for (int i = 0; i < N; i++){
    		int less_count = gTreap.GetLessK(gTreap.root, gPoints[i].x);
    		gCoverNum[less_count] ++;
    
    		gTreap.Insert(gTreap.root, gPoints[i].x);
    
    	/*rintf("##################
    ");
    		gTreap.debug(gTreap.root);
    		printf("##################
    ");
    		*/
    
    	}
    	for (int i = 0; i < N; i++){
    		printf("%d
    ", gCoverNum[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    css选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联和important哪个优先
    移动端重要的几个CSS3属性设置
    关于移动端的Click事件
    JS根据key值获取URL中的参数值,以及把URL的参数转换成json对象
    动态添加JS文件到页面
    JS 模拟C# 字符串格式化操作
    JS cookie 读写操作
    很好用的Tab标签切换功能,延迟Tab切换。
    SpringMVC 原理
    SpringMVC 三种异常处理方式
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4715457.html
Copyright © 2011-2022 走看看