CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化
题目链接:
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 离线线段树 单点更新 离散化相关推荐
- HDUOJ----1166敌兵布阵(线段树单点更新)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 【原创】tyvj1038 忠诚 计蒜客 管家的忠诚 线段树(单点更新,区间查询)...
[原创]tyvj1038 忠诚 & 计蒜客 管家的忠诚 & 线段树(单点更新,区间查询) 最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不 ...
- poj 2892---Tunnel Warfare(线段树单点更新、区间合并)
题目链接 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensiv ...
- HDU - 1166敌兵布阵+HDU-1754 I Hate It (线段树单点更新——累加/最大值)
线段树单点更新,模板题 HDU1166 敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和T ...
- “玲珑杯”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 ...
- 线段树(单点更新,区间查询) HDU 1754 I Hate It
题目链接 线段树的模板 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include&l ...
- FZU 2297 Number theory【线段树/单点更新/思维】
Given a integers x = 1, you have to apply Q (Q ≤ 100000) operations: Multiply, Divide. Input First l ...
- CDOJ 1073 线段树 单点更新+区间查询 水题
H - 秋实大哥与线段树 Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%lld & %llu Submit S ...
- hdu4046 不错的线段树单点更新
题意: 给一个字符串,两种操作 0 a b 询问a,b之间有多少个wbw, 1 a c 就是把第a个改成c. 思路: 这个题目我们可以用线段树的点更新来做,一开始写了个好长好长 ...
最新文章
- 【 FPGA 】7 Series FPGA中对MUX的设计指导
- 比特币交易构成(二)
- ICML论文|这违反直觉的“升噪”方法,反而能很好的解决激活函数梯度弥散的问题
- [Swift]LeetCode781. 森林中的兔子 | Rabbits in Forest
- 深度学习在CV领域的进展以及一些由深度学习演变的新技术
- mac 如何配置mysql_MAC下安装与配置MySQL
- VM虚拟机里怎么安装ubuntu-16.04.5-desktop-amd64.iso
- html上传视频文件前端显示,文件分片上传之前端文件分片
- Good Bye 2016 //智商再次下线,边界爆炸.....
- 试试看读一下Zepto源码
- 杭州互联网公司和生活成本
- js基础之六种继承方式
- java打印日历至Excel_如何利用Excel打印漂亮的工作日历
- [Bullet3]常见物体和初始化
- 多个同1div float left换行题
- 微信小程序出现报错:Uncaught ReferenceError: __g is not defined
- 15款jQuery幻灯片插件
- 字符串大小比较的规则?
- Qt常用轮子合集(带使用Demo)
- SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
热门文章
- Delphi中文件名函数-路径、名称、子目录、驱动器、扩展名
- iPhone开发进阶(9)--- 用SQLite管理数据库
- 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET - 插件标记实现
- 【LeetCode】198.打家劫舍
- 反弹c语言作业,C语言实现反弹球小游戏
- java threadgourp_Java Thread getThreadGroup()方法
- iscsi发起程序找不到目标_3分钟学会程序员“面试回答规范”,不怕找不到工作的里面请...
- dell存储Linux配置,Dell MD3200远程存储的特殊配置
- python做马里奥_python实现超级马里奥
- vue php 增删改查,vue的增删改查(简单版)