Description

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.

Sample
Input

Input
7
add 1 1
add 3 4
find 0 0
remove 1 1
find 0 0
add 1 1
find 0 0
Output
1 1
3 4
1 1
Input
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
Output
7 7
-1
5 5

这题我想了很久,有个地方一直错,导致我改了好几天才该对了这题。。这题题意是共有三种操作,添加点,删除点以及查找严格右上方的点。
这里可以先读入所有坐标后去重,然后对于每一个x坐标,维护一个set记录该x坐标下的所有y坐标,便于添加点或者删除点后查找最大的y坐标。然后用线段树维护横坐标上的最大y坐标,便于快速查找。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 200060
int pos[maxn],high[maxn],zhi,ans;
struct node{
int l,r,h;
}b[4*maxn];
char s[maxn][10];
set<int> myset[maxn];
set<int>::iterator it;
int find(int l,int r,int x)
{
int mid;
while(l<=r){
mid=(l+r)/2;
if(pos[mid]==x)return mid;
else if(pos[mid]>x)r=mid-1;
else l=mid+1;
}
if(pos[l]==x)return l;
else return r;
} void build(int l,int r,int i)
{
int mid;
b[i].l=l;b[i].r=r;b[i].h=0;
if(l==r)return;
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
} void update(int t1,int i)
{
int mid;
if(b[i].l==t1 && b[i].r==t1){
if(myset[t1].size())
b[i].h=*(--myset[t1].end());
else
b[i].h=-1;
return;
}
mid=(b[i].l+b[i].r)/2;
if(t1>mid)update(t1,i*2+1);
else update(t1,i*2);
b[i].h=max(b[i*2].h,b[i*2+1].h);
} void question(int l,int r,int h,int i)
{
int mid;
if(b[i].h<=h || r>b[i].r || l<b[i].l)return; //这里要注意可能一开始r,l就在区间内
if(b[i].l==b[i].r){
if(b[i].h<=h)return;
ans=b[i].l;return;
}
mid=(b[i].l+b[i].r)/2;
if(r<=mid){
if(b[i*2].h>h){
question(l,r,h,i*2);
}
else return;
}
else if(l>mid){
if(b[i*2+1].h>h){
question(l,r,h,i*2+1);
}
else return;
}
else{
if(b[i*2].h>h)question(l,mid,h,i*2);
if(ans!=-1)return; //这里是关键!如果左子树查不到的话,要查右子树,并不是如果左子树记录的最大高度大于h,就一定能找到,因为左子树还有自身的l限制(即l并不延伸到b[i].l)
if(b[i*2+1].h>h)question(mid+1,r,h,i*2+1);
else return;
}
} int main()
{
int n,m,i,j,t,t1,t2,c[maxn],d[maxn];//,ans
while(scanf("%d",&n)!=EOF)
{
t=0;
for(i=1;i<=n;i++){
scanf("%s%d%d",s[i],&c[i],&d[i]);
if(s[i][0]=='a'){
++t;pos[t]=c[i];
}
}
sort(pos+1,pos+1+t);
m=1;
for(i=2;i<=t;i++){
if(pos[i]!=pos[m]){
m++;pos[m]=pos[i];
}
}
build(1,m,1);
memset(high,-1,sizeof(high));
for(i=1;i<=m;i++){
myset[i].clear();
}
for(i=1;i<=n;i++){
if(s[i][0]=='a'){
t1=find(1,m,c[i]);
myset[t1].insert(d[i]);
update(t1,1);
}
else if(s[i][0]=='r'){
t1=find(1,m,c[i]);
myset[t1].erase(d[i]);
update(t1,1);
}
else
{
t2=upper_bound(pos+1,pos+1+m,c[i])-pos;
if(t2>m){
printf("-1\n");continue;
}
ans=-1;
question(t2,m,d[i],1);
if(ans==-1)
printf("-1\n");
else
printf("%d %d\n",pos[ans],*myset[ans].upper_bound(d[i]));
}
}
}
return 0;
}

最新文章

  1. Bash&#160;.&#160;configure&#160;permission&#160;denied错误
  2. idea 使用
  3. ASP.NET MVC开发微信(三)
  4. 使用visual studio 2015调用阿里云oss .net sdk 2.2的putobject接口抛出outofmemory异常
  5. 创建一个目录info,并在目录中创建一个文件test.txt,把该文件的信息读取出来,并显示出来
  6. Oracle database server 安装tips
  7. NOIP200701
  8. ubuntu14.04 swap not avalible交换分区不能使用
  9. windows下fitness python版本安装测试
  10. Java的位运算符具体解释实例——与(&amp;amp;)、非(~)、或(|)、异或(^)
  11. System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(string, string)已过时的解决办法
  12. 为什么MD5不能解密
  13. canvas探照灯效果
  14. js中this最简单清晰的解释
  15. phpStorm ctrl+左键无法找到类
  16. (并发编程)线程 (理论-创建-lock-属性-守护,与进程的对比)
  17. 第5章 IP地址和子网划分(2)_IP地址分类和NAT技术
  18. hive 1.2 配置
  19. [Oracle]如何查看一个数据文件是否是自动扩展
  20. oracle9i-11.2安装包及补丁包下载链接

热门文章

  1. mmall商城购物车模块总结
  2. (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建
  3. CMU数据库(15-445)实验2-b+树索引实现(上)
  4. python多线程和GIL全局解释器锁
  5. django模板中导入js、css等静态文件
  6. C#高级编程第11版 - 第七章 索引
  7. Canal介绍以及应用
  8. 自修改代码 on the fly 动态编译 即时编译 字节码
  9. MonkeyRunner使用
  10. socket创建和结束