题目链接:

http://codeforces.com/contest/19/problem/D

题意:

有三种操作“add x y”往平面上添加(x,y)这个点,”remove x y”,将平面上已经存在的点(x,y)删除,“find x y”找出平面上坐标严格大于(x,y)的点,如果有多个点找x最小的,再找y最小的。

题解:

所有点 x 坐标离散化,然后按照新的坐标建一个线段树。
对于每一个坐标x,维护一个set,add操作在相应的set里加入y,remove操作在相应的set里减去y。再有一个mx[]数组来维护最值。每次add、remove操作通过pushup操作更新最值。find操作先在左子树找,如果没找到再跑到右子树,使得x最小。

代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 #define MS(a) memset(a,0,sizeof(a))
  5 #define MP make_pair
  6 #define PB push_back
  7 const int INF = 0x3f3f3f3f;
  8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
  9 inline ll read(){
 10     ll x=0,f=1;char ch=getchar();
 11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 13     return x*f;
 14 }
 15 //
 16 const int maxn = 210000;
 17
 18 int n,x[maxn],y[maxn],tmp[maxn];
 19 char op[maxn][8];
 20
 21 struct node{
 22     int l,r,mx;
 23 }tree[maxn<<2];
 24
 25 set<int> s[maxn];
 26
 27 void build(int rt,int l,int r){
 28     tree[rt].l=l,tree[rt].r=r,tree[rt].mx=0;
 29     if(l == r) { s[l].clear(); return ;}
 30     int mid = (l+r)/2;
 31     build(rt<<1,l,mid);
 32     build(rt<<1|1,mid+1,r);
 33 }
 34
 35 void pushup(int rt){
 36     tree[rt].mx = max(tree[rt<<1].mx, tree[rt<<1|1].mx);
 37 }
 38
 39 void add(int rt,int pos,int val){
 40     int l = tree[rt].l, r = tree[rt].r;
 41     if(l == r){
 42         s[l].insert(val);
 43         tree[rt].mx = max(tree[rt].mx,val);
 44         return ;
 45     }
 46     int mid = (l+r) / 2;
 47     if(pos <= mid) add(rt<<1,pos,val);
 48     else add(rt<<1|1,pos,val);
 49     pushup(rt);
 50 }
 51
 52 void move(int rt,int pos,int val){
 53     int l = tree[rt].l,r=tree[rt].r;
 54     if(l == r){
 55         s[l].erase(val);
 56         tree[rt].mx = s[l].empty() ? 0 : *--s[l].end();
 57         return ;
 58     }
 59     int mid = (l+r)/2;
 60     if(pos <= mid) move(rt<<1,pos,val);
 61     else move(rt<<1|1,pos,val);
 62     pushup(rt);
 63 }
 64
 65 pair<int,int> find(int rt,int pos,int val){
 66     int l=tree[rt].l,r=tree[rt].r;
 67     if(tree[rt].mx<val || r<pos) return make_pair(l,-1);
 68
 69     if(l == r){
 70         return make_pair(l,*s[l].lower_bound(val));
 71     }
 72     pair<int,int> res = find(rt<<1,pos,val);
 73     if(res.second != -1) return res;
 74     else return find(rt<<1|1,pos,val);
 75 }
 76
 77 int main(){
 78     cin >> n;
 79     int cnt = 0;
 80     for(int i=0; i<n; i++){
 81         scanf("%s%d%d",op[i],&x[i],&y[i]);
 82         tmp[cnt++] = x[i];
 83     }
 84     sort(tmp,tmp+cnt);
 85     cnt = unique(tmp,tmp+cnt)-tmp;
 86     // for(int i=0; i<cnt; i++)
 87     //  cout << tmp[i] << " ";
 88     // puts("");
 89     build(1,0,cnt-1);
 90
 91     for(int i=0; i<n; i++){
 92         int pos = lower_bound(tmp,tmp+cnt,x[i])-tmp;
 93         // cout << pos << endl;
 94         if(op[i][0] == 'a') add(1,pos,y[i]);
 95         else if(op[i][0] == 'r') move(1,pos,y[i]);
 96         else {
 97             pair<int,int> ans = find(1,pos+1,y[i]+1);
 98             // cout << pos+1 << endl;
 99             if(ans.second == -1) puts("-1");
100             else cout << tmp[ans.first] << " " << ans.second << endl;
101         }
102     }
103
104     return 0;
105 }

转载于:https://www.cnblogs.com/yxg123123/p/6827572.html

CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化相关推荐

  1. HDUOJ----1166敌兵布阵(线段树单点更新)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  2. 【原创】tyvj1038 忠诚 计蒜客 管家的忠诚 线段树(单点更新,区间查询)...

    [原创]tyvj1038 忠诚 & 计蒜客 管家的忠诚 & 线段树(单点更新,区间查询) 最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不 ...

  3. poj 2892---Tunnel Warfare(线段树单点更新、区间合并)

    题目链接 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensiv ...

  4. HDU - 1166敌兵布阵+HDU-1754 I Hate It (线段树单点更新——累加/最大值)

    线段树单点更新,模板题 HDU1166 敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和T ...

  5. “玲珑杯”ACM比赛 Round #21-C-战舰萝莉(线段树区间更新)

    "玲珑杯"ACM比赛 Round #21 Start Time:2017-09-23 17:00:00 End Time:2017-09-23 19:30:00 Refresh T ...

  6. 线段树(单点更新,区间查询) HDU 1754 I Hate It

    题目链接 线段树的模板 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include&l ...

  7. FZU 2297 Number theory【线段树/单点更新/思维】

    Given a integers x = 1, you have to apply Q (Q ≤ 100000) operations: Multiply, Divide. Input First l ...

  8. CDOJ 1073 线段树 单点更新+区间查询 水题

    H - 秋实大哥与线段树 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Submit S ...

  9. hdu4046 不错的线段树单点更新

    题意:       给一个字符串,两种操作 0 a b 询问a,b之间有多少个wbw, 1 a c 就是把第a个改成c. 思路:       这个题目我们可以用线段树的点更新来做,一开始写了个好长好长 ...

最新文章

  1. 【 FPGA 】7 Series FPGA中对MUX的设计指导
  2. 比特币交易构成(二)
  3. ICML论文|这违反直觉的“升噪”方法,反而能很好的解决激活函数梯度弥散的问题
  4. [Swift]LeetCode781. 森林中的兔子 | Rabbits in Forest
  5. 深度学习在CV领域的进展以及一些由深度学习演变的新技术
  6. mac 如何配置mysql_MAC下安装与配置MySQL
  7. VM虚拟机里怎么安装ubuntu-16.04.5-desktop-amd64.iso
  8. html上传视频文件前端显示,文件分片上传之前端文件分片
  9. Good Bye 2016 //智商再次下线,边界爆炸.....
  10. 试试看读一下Zepto源码
  11. 杭州互联网公司和生活成本
  12. js基础之六种继承方式
  13. java打印日历至Excel_如何利用Excel打印漂亮的工作日历
  14. [Bullet3]常见物体和初始化
  15. 多个同1div float left换行题
  16. 微信小程序出现报错:Uncaught ReferenceError: __g is not defined
  17. 15款jQuery幻灯片插件
  18. 字符串大小比较的规则?
  19. Qt常用轮子合集(带使用Demo)
  20. SqlNullValueException: Data is Null. This method or property cannot be called on Null values.

热门文章

  1. Delphi中文件名函数-路径、名称、子目录、驱动器、扩展名
  2. iPhone开发进阶(9)--- 用SQLite管理数据库
  3. 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET - 插件标记实现
  4. 【LeetCode】198.打家劫舍
  5. 反弹c语言作业,C语言实现反弹球小游戏
  6. java threadgourp_Java Thread getThreadGroup()方法
  7. iscsi发起程序找不到目标_3分钟学会程序员“面试回答规范”,不怕找不到工作的里面请...
  8. dell存储Linux配置,Dell MD3200远程存储的特殊配置
  9. python做马里奥_python实现超级马里奥
  10. vue php 增删改查,vue的增删改查(简单版)