CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化
2017-03-24 19:39
330 查看
题目链接:
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最小。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define MS(a) memset(a,0,sizeof(a)) #define MP make_pair #define PB push_back const int INF = 0x3f3f3f3f; const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ////////////////////////////////////////////////////////////////////////// const int maxn = 210000; int n,x[maxn],y[maxn],tmp[maxn]; char op[maxn][8]; struct node{ int l,r,mx; }tree[maxn<<2]; set<int> s[maxn]; void build(int rt,int l,int r){ tree[rt].l=l,tree[rt].r=r,tree[rt].mx=0; if(l == r) { s[l].clear(); return ;} int mid = (l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void pushup(int rt){ tree[rt].mx = max(tree[rt<<1].mx, tree[rt<<1|1].mx); } void add(int rt,int pos,int val){ int l = tree[rt].l, r = tree[rt].r; if(l == r){ s[l].insert(val); tree[rt].mx = max(tree[rt].mx,val); return ; } int mid = (l+r) / 2; if(pos <= mid) add(rt<<1,pos,val); else add(rt<<1|1,pos,val); pushup(rt); } void move(int rt,int pos,int val){ int l = tree[rt].l,r=tree[rt].r; if(l == r){ s[l].erase(val); tree[rt].mx = s[l].empty() ? 0 : *--s[l].end(); return ; } int mid = (l+r)/2; if(pos <= mid) move(rt<<1,pos,val); else move(rt<<1|1,pos,val); pushup(rt); } pair<int,int> find(int rt,int pos,int val){ int l=tree[rt].l,r=tree[rt].r; if(tree[rt].mx<val || r<pos) return make_pair(l,-1); if(l == r){ return make_pair(l,*s[l].lower_bound(val)); } pair<int,int> res = find(rt<<1,pos,val); if(res.second != -1) return res; else return find(rt<<1|1,pos,val); } int main(){ cin >> n; int cnt = 0; for(int i=0; i<n; i++){ scanf("%s%d%d",op[i],&x[i],&y[i]); tmp[cnt++] = x[i]; } sort(tmp,tmp+cnt); cnt = unique(tmp,tmp+cnt)-tmp; // for(int i=0; i<cnt; i++) // cout << tmp[i] << " "; // puts(""); build(1,0,cnt-1); for(int i=0; i<n; i++){ int pos = lower_bound(tmp,tmp+cnt,x[i])-tmp; // cout << pos << endl; if(op[i][0] == 'a') add(1,pos,y[i]); else if(op[i][0] == 'r') move(1,pos,y[i]); else { pair<int,int> ans = find(1,pos+1,y[i]+1); // cout << pos+1 << endl; if(ans.second == -1) puts("-1"); else cout << tmp[ans.first] << " " << ans.second << endl; } } return 0; }
相关文章推荐
- CodeForces 19D Points(离散化+线段树+单点更新)
- CodeForces 19D Points(离散化+线段树+单点更新)
- hdu4288 Coder 离线线段树 单点更新 区间求和 离散化?
- 2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化
- hdoj 4325 Flowers 【线段树 + 离散化】【区间更新 单点查询】
- POJ 2828 线段树单点更新 离线搞
- HDU 3874 Necklace (线段树单点更新+区间查询+离线操作)
- hdu3874 线段树单点更新+离线处理
- CodeForces 19D Points(线段树单点修改+离散化)
- HDOJ 4325 Flowers 【线段树 离散化 区间更新 单点查询】
- 【CodeForces】 19D Points(线段树|单点更新)
- hdu4417:线段树单点更新区间求和,离线 Super Mario
- 【HDU4288 Coder】离线+离散化+5颗线段树的更新操作
- .CodeforcesBeta Round #19 D. Points 线段树 单点更新
- POJ 2828 线段树单点更新 离线搞
- Necklace (线段树单点更新+区间查询+离线操作)
- 线段树单点更新+区间更新+离散化
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
- POJ 2528:Mayor's posters(线段树区间更新+离散化)
- 单点更新线段树 RMQ