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浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4715457.html
Copyright © 2011-2022 走看看