题目链接:
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 }