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 UI设计--半透明效果对话框及activity(可做遮罩层)
下面是style的一些属性及其解释 <style name="dialog_translucent" parent="@android:style/Theme.Di ...
- GridView动态添加View
activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...
- 什么是 Linux 发行版
什么是Linux的发行版 就Linux的本质来说,它只是操作系统的核心,负责控制硬件.管理文件系统.程序进程等,并不给用户提供各种工具和应用软件.所谓工欲善其事,被必先利其器,一套在优秀的操作系统核心 ...
- 数据结构之区间K大数
求区间的问题有很多类,虽然前人有很多讲解了: 但是我在这里在普及一下,算是自己的一种复习吧. 1.静态询问一个区间的的第k大数,比如询问[l,r] k大数.虽然主席树可以处理,但是这类问题应该是划分树 ...
- Linux下运行Java项目时,出现No X11 DISPLAY variable was set, but this program performed an operation which requires it.的问题解决
在~/.bashrc环境变量文件最下方加入: export DISPLAY=:0.0 然后,刷新环境变量以使其生效: source -/.bashrc 参考:http://stackoverflow. ...
- vim 精确匹配查找单词【转】
删除文件中所有的空行:g/^\s*$/d 去掉所有的行尾空格::%s/\s\+$// 整个文件特定字符串的替换:%s/old_word/new_word/g 删除从当前行开始到最后一行的所有内容:., ...
- malloc动态分配多维数组
下面试自己写的三个测试程序,如果看懂了基本上动态分配多维数组就没什么问题啦:重点 1:深刻理解多维数组的概念,多维数组在内存中的分配情况,基本上动态分配也没什么问题的.然后还要注意一点的就是,释放是分 ...
- Vue 开发线路 资料 汇总
线路 作者推荐学习线路 https://zhuanlan.zhihu.com/p/23134551 他人建议 https://www.cnblogs.com/smartXiang/p/6051086. ...
- 项目Beta冲刺(团队3/7)
项目Beta冲刺(团队3/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...
- Hadoop源代码分析(完整版)
Hadoop源代码分析(一) 关键字: 分布式云计算 Google的核心竞争技术是它的计算平台.Google的大牛们用了下面5篇文章,介绍了它们的计算设施. GoogleCluster:http:// ...