CodeForces19D:Points(线段树+set(动态查找每个点右上方的点))
Pete and Bob invented a new interesting game. Bob takes a sheet of paper and locates a Cartesian coordinate system on it as follows: point (0, 0) is located in the bottom-left corner, Ox axis is directed right, Oy axis is directed up. Pete gives Bob requests of three types:
- add x y — on the sheet of paper Bob marks a point with coordinates (x, y). For each request of this type it's guaranteed that point (x, y) is not yet marked on Bob's sheet at the time of the request.
- remove x y — on the sheet of paper Bob erases the previously marked point with coordinates (x, y). For each request of this type it's guaranteed that point (x, y) is already marked on Bob's sheet at the time of the request.
- find x y — on the sheet of paper Bob finds all the marked points, lying strictly above and strictly to the right of point (x, y). Among these points Bob chooses the leftmost one, if it is not unique, he chooses the bottommost one, and gives its coordinates to Pete.
Bob managed to answer the requests, when they were 10, 100 or 1000, but when their amount grew up to 2·105, Bob failed to cope. Now he needs a program that will answer all Pete's requests. Help Bob, please!
Input
The first input line contains number n (1 ≤ n ≤ 2·105) — amount of requests. Then there follow n lines — descriptions of the requests. add x y describes the request to add a point, remove x y — the request to erase a point, find x y — the request to find the bottom-left point. All the coordinates in the input file are non-negative and don't exceed 109.
Output
For each request of type find x y output in a separate line the answer to it — coordinates of the bottommost among the leftmost marked points, lying strictly above and to the right of point (x, y). If there are no points strictly above and to the right of point (x, y), output -1.
Example
7
add 1 1
add 3 4
find 0 0
remove 1 1
find 0 0
add 1 1
find 0 0
1 1
3 4
1 1
13
add 5 5
add 5 6
add 5 7
add 6 5
add 6 6
add 6 7
add 7 5
add 7 6
add 7 7
find 6 6
remove 7 7
find 6 6
find 4 4
7 7
-1
5 5
题意:给定二维平面,有Q个操作。对于每个操作,输入Opt,X,Y。
如果Opt==“add”,则加(X,Y)。
如果Opt==“remove”,则删去(X,Y)
否则,查找(X,Y)右上方最靠左的点,若果有多个,取Y最小,输出坐标。
思路:离散化,对X轴建立线段树,树节点保存子树的最大Y坐标值Max。利用线段树查找的思想相当于是分治吧,即,在查找(X,Y)右上方点时,只要找到X的右边部分的线段树里第一个Max>Y,得到X’,然后set二分得到Y‘就ok。
(为了统一,我新习惯把单点也看成区间。)
#include<set>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int x[maxn],y[maxn],opt[maxn],a[maxn];
char chr[]; set<int>s[maxn];
void read(int &res){
char c=getchar(); for(;c>''||c<'';c=getchar());
for(res=;c>=''&&c<='';c=getchar()) res=(res<<)+(res<<)+c-'';
}
int Max[maxn<<],ans,ht;
struct segment_tree
{
void add(int Now,int L,int R,int l,int r,int Y)
{
if(l<=L&&r>=R){
s[l].insert(Y);
Max[Now]=*(s[l].rbegin());
return ;
}
int Mid=(L+R)>>;
if(l<=Mid) add(Now<<,L,Mid,l,r,Y);
if(r>Mid) add(Now<<|,Mid+,R,l,r,Y);
Max[Now]=max(Max[Now<<],Max[Now<<|]);
}
void del(int Now,int L,int R,int l,int r,int Y)
{
if(l<=L&&r>=R){
s[l].erase(Y);
if(s[l].empty()) Max[Now]=-;
else Max[Now]=*(s[l].rbegin());
return ;
}
int Mid=(L+R)>>;
if(l<=Mid) del(Now<<,L,Mid,l,r,Y);
if(r>Mid) del(Now<<|,Mid+,R,l,r,Y);
Max[Now]=max(Max[Now<<],Max[Now<<|]);
}
void find(int Now,int L,int R,int l,int r,int Y)
{
if(Max[Now]<=Y) return ;
if(l<=L&&r>=R){
if(L==R){
ans=L; ht=*(s[L].upper_bound(Y));
return ;
}
int Mid=(L+R)>>;
find(Now<<,L,Mid,l,r,Y);
if(ans==-) find(Now<<|,Mid+,R,l,r,Y);
return ;
}
int Mid=(L+R)>>;
if(l<=Mid) find(Now<<,L,Mid,l,r,Y);
if(ans==-&&r>Mid) find(Now<<|,Mid+,R,l,r,Y);
}
}Tree;
int main()
{
int N,M;
read(N);
for(int i=;i<=N;i++){
scanf("%s",chr); read(x[i]); read(y[i]);
if(chr[]=='r') opt[i]=-;
if(chr[]=='a') opt[i]=;
if(chr[]=='f') opt[i]=;
a[i]=x[i];
}
sort(a+,a+N+);
M=unique(a+,a+N+)-(a+);
for(int i=;i<=N;i++){
int X=lower_bound(a+,a+M+,x[i])-a;
if(opt[i]==) Tree.add(,,M,X,X,y[i]);
else if(opt[i]==-) Tree.del(,,M,X,X,y[i]);
else{
ans=ht=-;
Tree.find(,,M,X+,M,y[i]);
if(ans==-) printf("-1\n");
else printf("%d %d\n",a[ans],ht);
}
}
return ;
}
CodeForces19D:Points(线段树+set(动态查找每个点右上方的点))的更多相关文章
- [Codeforces19D]Points 线段树
大致题意: 给出n个询问,每次询问有三种: 1.往平面上加一个点 2.删除平面上的一个点 3.给出一个点p,查询平面上某点q,使得q.x>p.x且q.y>p.y,输出x轴坐标最小的q,若有 ...
- 【xsy3423】党² 线段树+李超线段树or动态半平面交
本来并不打算出原创题的,此题集CF542A和sk的灵感而成,算个半原创吧. 题目大意: 给定有$n$个元素的集合$P$,其中第$i$个元素中包含$L_i,R_i,V_i$三个值. 给定另一个有$n$个 ...
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- CodeForces 19D Points (线段树+set)
D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)
Extending Set of Points 我们能发现, 如果把x轴y轴看成点, 那么答案就是在各个连通块里面的x轴的个数乘以y轴的个数之和. 然后就变成了一个并查集的问题, 但是这个题目里面有撤 ...
- BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)
题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...
- [hdu4347]The Closest M Points(线段树形式kd-tree)
解题关键:kdtree模板题,距离某点最近的m个点. #include<cstdio> #include<cstring> #include<algorithm> ...
- bzoj2212 Tree Rotations 线段树合并+动态开点
题目传送门 思路: 区间合并线段树的题,第一次写,对于一颗子树,无论这个子树怎么交换,都不会对其他子树的逆序对造成影响,所以就直接算逆序对就好. 注意叶子节点是1到n的全排列,所以每个权值都只会出现1 ...
- kb-07线段树-12--二分查找区间边界
/* hdu4614 本题刚开始想能不能记录该区间最前面开始的点,最后面的点,区间空的数量:但是病不行 然后线段树的本质是区间操作,所以!这题主要就是区间的空的全放满,只要定出区间的边界就好办了: 这 ...
随机推荐
- android获取手机号
private String getPhoneNum(){ //与手机建立连接 TelephonyManager tm = (TelephonyManager)getSystemService(Con ...
- 校园网、教育网 如何纯粹访问 IPv6 网站避免收费
我国校园网有可靠的 IPv6 网络环境,速度非常快.稳定,并且大多数高校在网络流量计费时不会限制 IPv6 的流量,也就是免费的.然而访问 IPv4 商业网络时,则会收费,并且连接的可靠性一般.可幸的 ...
- 【深度探索c++对象模型】关于对象
Linux进程的五个段 BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属 ...
- Python基础语法07--面向对象+正则表达式
Python 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触过 ...
- 自己动手写CPU之第九阶段(4)——载入存储指令实现思路
将陆续上传新书<自己动手写CPU>,今天是第40篇,我尽量每周四篇,可是近期已经非常久没有实现这个目标了,一直都有事,不好意思哈. 开展晒书评送书活动,在q=%E4%BA%9A%E9%A9 ...
- 常见iOS面试题 之 怎么判断一个类是否遵循某个协议
答案: 使用方法conformsToProtocol. 调用例子: BOOL isConform = [Student conformsToProtocol:@protocol(UIScrollVie ...
- 如何给老婆解释什么是RESTful
如何给老婆解释什么是RESTful Javdroider Hong 知乎专栏<Beautiful Java>的作者,一个热爱足球和健身的上进boy 1,543 人赞了该文章 老婆经常喜欢翻 ...
- wxWidgets刚開始学习的人导引(6)——wxWidgets学习材料清单
wxWidgets刚開始学习的人导引全文件夹 PDF版及附件下载 1 前言2 下载.安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用wx ...
- MySql 查询一周内记录
本周内:select * from wap_content where week(created_at) = week(now) 查询一天:select * from table where to_d ...
- mysqld与mysqld_safe的区别
文章1: 直接运行mysqld程序来启动MySQL服务的方法很少见,mysqld_safe脚本会在启动MySQL服务器后继续监控其运行情况,并在其死机时重新启动它.用mysqld_safe脚本来启动M ...