题目链接:http://codeforces.com/contest/19/problem/D

题意:给出3种操作:1)添加点(x,y),2)删除点(x,y),3)查询离(x,y)最近的右上方的点。

且满足添加的点不重复,删除的点一定存在。

题解:只要以x建树,记录下每个结点最大的y值。每次都更新一下。用线段树查找满足条件的最小的x,然后用一个set[x]来存x点下的y点。

然后用二分查找满足条件的最小的y。

#include <iostream>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;
const int M = 2e5 + 10;
struct T_T {
char cp[10];
int x , y;
}num[M];
struct TnT {
int l , r , max_y;
}T[M << 2];
set<int>se[M];
set<int>::iterator it;
int a[M] , b[M] , c[M] , d[M];
void build(int l , int r , int p) {
int mid = (l + r) >> 1;
T[p].l = l , T[p].r = r , T[p].max_y = -1;
if(T[p].l == T[p].r) {
return;
}
build(l , mid , p << 1);
build(mid + 1 , r , (p << 1) | 1);
T[p].max_y = max(T[p << 1].max_y , T[(p << 1) | 1].max_y);
}
void updata(int p , int pos) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == T[p].r && T[p].l == pos) {
if(se[T[p].l].size()) {
it = (--se[T[p].l].end());
T[p].max_y = *it;
}
else {
T[p].max_y = -1;
}
return ;
}
if(mid >= pos) {
updata(p << 1 , pos);
}
else {
updata((p << 1) | 1 , pos);
}
T[p].max_y = max(T[p << 1].max_y , T[(p << 1) | 1].max_y);
}
int query(int p , int x , int y) {
if(T[p].r <= x) {
return -1;
}
if(T[p].max_y <= y) {
return -1;
}
if(T[p].l == T[p].r) {
return T[p].r;
}
int t = query(p << 1 , x , y);
if(t == -1)
return query((p << 1) | 1 , x , y);
return t;
}
int main() {
int n;
scanf("%d" , &n);
int count = 0;
for(int i = 0 ; i < n ; i++) {
scanf("%s %d %d" , num[i].cp , &num[i].x , &num[i].y);
if(num[i].cp[0] == 'a') {
a[count++] = num[i].x;
}
}
sort(a , a + count);
int cnt = 0;
a[count] = -1;
for(int i = 0 ; i < count ; i++) {
if(a[i] != a[i + 1]) {
b[cnt++] = a[i];
}
}
build(1 , M , 1);
for(int i = 0 ; i < n ; i++) {
if(num[i].cp[0] == 'a') {
int pos = upper_bound(b , b + cnt , num[i].x) - b;
se[pos].insert(num[i].y);
updata(1 , pos);
}
if(num[i].cp[0] == 'r') {
int pos = upper_bound(b , b + cnt , num[i].x) - b;
se[pos].erase(num[i].y);
updata(1 , pos);
}
if(num[i].cp[0] == 'f') {
int pos = upper_bound(b , b + cnt , num[i].x) - b;
int poss = query(1 , pos , num[i].y);
if(poss != -1) {
printf("%d %d\n" , b[poss - 1] , *se[poss].upper_bound(num[i].y));
}
else {
printf("-1\n");
}
}
}
return 0;
}

最新文章

  1. 【MongoDB】6.关于MongoDB存储文件的 命令执行+代码执行
  2. 如何阻止SELECT * 语句
  3. 李洪强iOS经典面试题130
  4. js实现黑客帝国二进制雨
  5. flex布局中flex-basis|flex-grow|flex-shrink
  6. hdu 5203
  7. COJ 2124 Day8-例1
  8. hdu3656Fire station(DLX重复覆盖 + 二分)
  9. SharePoint 2010以其他用户身份登录的弹出代码
  10. Tensorflow笔记一
  11. MT7688交叉编译环境配置
  12. H5 14-后代选择器和子元素选择器
  13. List&lt;&gt; of struct with property. Cannot change value of property. why?
  14. 剑指offer.找出数组中重复的数字
  15. 【贪心策略】USACO 越野跑
  16. ngx_lua_API 指令详解(三)怎样理解 cosocket指令
  17. PAT 甲级 1142 Maximal Clique
  18. 数据库 Proc编程一
  19. OPEN(SAP) UI5 学习入门系列之三:MVC (下) - 视图与控制器
  20. simpleDateFormat的 学习

热门文章

  1. RocketMQ中Broker的启动源码分析(二)
  2. Python 使用k-means方法将列表中相似的句子聚为一类
  3. vue 辅助开发工具(利用node自动生成相关文件,自动注册路由)
  4. Android——倒计时跳转+sharedpreferences
  5. Ubuntu下安装php7.1的gd,mysql,pdo_mysql扩展库
  6. 《大牛到底是如何阅读JDK源码的?》一起来学习一下
  7. 使用charls抓包微信小程序的解决方案(终极解决,各种坑不怕,亲测可用,不服来战!)
  8. 消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!
  9. 目标检测YOLO进化史之yolov1
  10. Java中synchronized关键字你知道多少