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 }

 

posted @ 2017-03-24 19:39  _yxg123  阅读(149)  评论(0编辑  收藏  举报