题意:对于一个二维平面,有三种操作:1.add x y 代表 x y 这里有点 2.remove x y 代表删掉这个点 3. find x y 输出在这个点右上方最靠近这个点的坐标,如果没有输出-1.
数轴长度达到 1e9,然而点的个数最多只有 2*10^5,所以把点给离散化,然后用线段树维护区间段内点的纵坐标的最大值。插入和删除的时候直接二分找到位置就可以。
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 2e5+10; int value[maxn<<3]; int flag[maxn]; struct node{ int x, y; bool operator <(const node&a) const{ if(x != a.x) return x<a.x; else return y<a.y; } }x[maxn], a[maxn], ans; void PushUp(int rt){ value[rt] = max(value[rt<<1], value[rt<<1|1]); } void update(bool f, int p, int add, int l, int r, int rt){ if(l==r){ value[rt] = f?add:-1; return; } int m = l + (r-l)/2; if(p <= m) update(f, p, add, lson); else update(f, p, add, rson); PushUp(rt); } void query(node a, int l,int r,int rt){ if(x[r].x <= a.x || value[rt]<= a.y) return; if(l == r) ans = x[l]; int m = l + (r-l)/2; query(a, lson); if(ans.x == -1) query(a, rson); } int main(){ //freopen("a.txt", "r", stdin); int n; while(~scanf("%d", &n)){ memset(value, -1, sizeof(value)); int m = 1; for(int i = 1; i <= n; i++){ char op[10]; scanf("%s %d %d", op, &a[i].x, &a[i].y); if(op[0] == 'a'){ x[m++] = a[i]; flag[i] = 1; }else if(op[0] == 'f'){ flag[i] = 2; } else flag[i] = 0; } sort(x+1, x+1+m); for(int i = 1; i <= n; i++){ if(flag[i] < 2){ int now = lower_bound(x+1, x+m+1, a[i])-x; update(flag[i], now, a[i].y, 1, m, 1); }else{ ans.x = -1, ans.y = -1; query(a[i], 1, m, 1); if(ans.x == -1) cout << "-1" << endl; else cout << ans.x << " " << ans.y << endl; } } } return 0; }