博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj_2352 Treap
阅读量:7029 次
发布时间:2019-06-28

本文共 2486 字,大约阅读时间需要 8 分钟。

题目大意

    对于二维平面上的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
#include
using namespace std;#define MAX_NODE_NUM 15500struct 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\n", 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("##################\n"); gTreap.debug(gTreap.root); printf("##################\n"); */ } for (int i = 0; i < N; i++){ printf("%d\n", gCoverNum[i]); } return 0;}

 

转载地址:http://xrrxl.baihongyu.com/

你可能感兴趣的文章
博前语
查看>>
Java SE核心之一:常用类,包装类,其他基本数据类型包装类。
查看>>
郑捷《机器学习算法原理与编程实践》学习笔记(第二章 中文文本分类(一))...
查看>>
python (ploit)
查看>>
Android 用achartengine 画折线图怎么显示不正确
查看>>
程序简单的测试与升级(暨实践第一次作业)
查看>>
信号处理
查看>>
【100题】第五十九题 用C++编写不能被继承的类
查看>>
轻描淡写
查看>>
mysql基本操作
查看>>
39.CSS3弹性伸缩布局【下】
查看>>
[javascript]图解+注释版 Ext.extend()
查看>>
我的前端工具集(七)div背景网格
查看>>
linux 下mongo 基础配置
查看>>
【Dubbo实战】 Dubbo+Zookeeper+Spring整合应用篇-Dubbo基于Zookeeper实现分布式服务(转)...
查看>>
JUnit单元测试中的setUpBeforeClass()、tearDownAfterClass()、setUp()、tearDown()方法小结
查看>>
java之jvm学习笔记六(实践写自己的安全管理器)
查看>>
Docker容器查看ip地址
查看>>
在PC端或移动端应用中接入商业QQ
查看>>
将python3.6软件的py文件打包成exe程序
查看>>