链接
http://codeforces.com/contest/19/problem/D
题意
给定n个操作,共有3种操作
- add x y
向坐标系中添加点(x,y) - del x y
向坐标系中删除点(x,y) - find x y
在坐标系中找到一点(x0,y0),满足x0>x and y0>y,如果有多个满足的,优先考虑x0最小,其次y0最小,输出这个点,如果不存在这样的点,输出-1;
分析
这里使用线段树,首先x,y均是1E9,考虑对x进行离散化,并以离散后的x建立一个线段树,线段树的一个节点[l,r]存储着离散后区间为[l,r]的信息,定义着一个max,代表当前区间所有点坐标的最大的y,若当前区间左子区间的max大于我们给的y,那么就进去看看找到的结果可不可行(y满足x可能不满足),不可行就进行右子区间的查找;还需要定义着一个set数组,set[a]中存储a没离散之前所对应的所有y坐标(可能存在一部分点x坐标相同,y坐标不同)当进行find x y操作时,首先lower_bound+1或upper_bound查询大于x的值,最后找到合适的set,在upper_bound即可;
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
using namespace std;
#define inf 0x7f7f7f7f
#define maxn 200005
#define N 200005
#define P 2
typedef long long ll;
int n, k, a[maxn], cnt;
char s[maxn][7];
int valx[maxn], valy[maxn];
struct Tree {
int l, r, max;
} tree[4 * maxn];
inline void push_up(int x) {
tree[x].max = max(tree[x << 1].max, tree[x << 1 | 1].max);
}
set<int> st[maxn];
void build(int x, int l, int r) {
tree[x].l = l, tree[x].r = r, tree[x].max = 0;
if (l == r)return;
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
push_up(x);
}
void update(int x, int pos, int val) {
int l = tree[x].l, r = tree[x].r;
if (l == r) {
st[pos].insert(val);
tree[x].max = *--st[pos].end();
return;
}
int mid = (l + r) >> 1;
if (pos <= mid)update(x << 1, pos, val);
else update(x << 1 | 1, pos, val);
push_up(x);
}
void del(int x, int pos, int val) {
int l = tree[x].l, r = tree[x].r;
if (l == r) {
st[l].erase(val);
tree[x].max = st[l].empty() ? 0 : *--st[l].end();
return;
}
int mid = (l + r) >> 1;
if (pos <= mid)del(x << 1, pos, val);
else del(x << 1 | 1, pos, val);
push_up(x);
}
pair<int, int> find(int x, int pos, int val) {
//cout << tree[x].max <<" " << val <<" " << tree[x].l <<" " <<x<<endl;
int l = tree[x].l, r = tree[x].r;
if(tree[x].max <= val || r < pos){
return make_pair(-1,0);
}
if (l == r){
return make_pair(l, *st[l].upper_bound(val));
}
int mid = (l + r) >> 1;
pair <int, int> p= find(x << 1, pos, val);
if (p.first != -1) return p;
return find(x << 1 | 1, pos, val);
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s%d%d", s[i], &valx[i], &valy[i]);
a[++cnt] = valx[i];
}
sort(a + 1, a + 1 + cnt);
int len = unique(a + 1, a + 1 + cnt) - a - 1;
build(1, 1, len);
for (int i = 1; i <= n; i++) {
if (s[i][0] == 'a') {
int pos = lower_bound(a + 1, a + 1 + len, valx[i]) - a;
update(1, pos, valy[i]);
} else if (s[i][0] == 'r') {
int pos = lower_bound(a + 1, a + 1 + len, valx[i]) - a;
del(1, pos, valy[i]);
} else {
int pos = upper_bound(a + 1, a + 1 + len, valx[i]) - a;
pair<int, int> p = find(1, pos, valy[i]);
if(p.first == -1) {
cout << -1 <<endl;
continue;
}
cout << a[p.first] << " " << p.second <<endl;
}
}
}