Points

CF#19D:http://codeforces.com/contest/19/problem/D

题意:给你一个点,add x,y表示向集合中添加一个点,remove x,y,表示删除集合中的一个点,find x,y,表示查询比x,y,严格大的点,没有输出-1.

题解;这一题是一道好题,我从中学到了很多东西。首先,这一题的正解是线段树+set。首先按照x值建树,set[i]维护的是x值是i的所有y的集合。同时线段树还维护一个最大值maxn。首先,是离散化。这里用map和vector巧妙的实现了,map[xx[i]]=i;即可。其次是set,当查询dao一个满足条件的x值的时候,要查询y值的时候,可以使用lower_bound来实现。还有就是,线段树的查询,与往常的查询不太一样,以前都是查询某个点的值,这里是查询比两个值大的区间端点,不是一个。最后就是,用vecotr去重的写法:xx.erase(unique(xx.begin(),xx.end()),xx.end());

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<map>
  7 #include<set>
  8 using namespace std;
  9 int n;
 10 map<int,int>Map;
 11 const int N=2*1e5+5;
 12 vector<int>xx;
 13 struct  action{
 14    int x;
 15    int y;
 16    char str[20];
 17    void add(){
 18      xx.push_back(x);
 19    }
 20 }OP[N];
 21 struct  Node{
 22   int l,r;
 23   int maxn;
 24   inline int  mid(){
 25      return (l+r)/2;
 26   }
 27 }num[N*4];
 28 void pushup(int rt){
 29     num[rt].maxn=max(num[rt<<1].maxn,num[rt<<1|1].maxn);
 30 }
 31 set<int>yy[N];
 32 void build(int l,int r,int rt){
 33     num[rt].l=l;
 34     num[rt].r=r;
 35     num[rt].maxn=-1;
 36     if(l==r){
 37         yy[l].clear();
 38         return;
 39     }
 40     int mid=(l+r)/2;
 41     build(l,mid,rt<<1);
 42     build(mid+1,r,rt<<1|1);
 43 }
 44 void insert(int pos,int y,int rt){
 45     if(num[rt].l==num[rt].r){
 46         yy[pos].insert(y);
 47         num[rt].maxn=*(--yy[pos].end());
 48         return;
 49     }
 50     int mid=num[rt].mid();
 51     if(mid>=pos)insert(pos,y,rt<<1);
 52     else insert(pos,y,rt<<1|1);
 53      pushup(rt);
 54 }
 55 void  remove(int pos,int y,int rt){
 56    if(num[rt].l==num[rt].r){
 57        yy[pos].erase(y);
 58        if(yy[pos].size()==0)num[rt].maxn=-1;
 59        else
 60        num[rt].maxn=*(--yy[pos].end());
 61        return;
 62     }
 63    int mid=num[rt].mid();
 64     if(mid>=pos)remove(pos,y,rt<<1);
 65     else remove(pos,y,rt<<1|1);
 66      pushup(rt);
 67 }
 68 Node query(int y,int rt,int x){
 69      if(num[rt].maxn<y||num[rt].r<x){
 70         Node t1;
 71         t1.l=-1;
 72         return t1;
 73      }
 74     if(num[rt].l==num[rt].r){
 75            Node tt;
 76            tt.l=num[rt].l;
 77            tt.r=*yy[num[rt].l].lower_bound(y);
 78           return tt;
 79     }
 80     Node tp=query(y,rt<<1,x);
 81     if(tp.l!=-1)return tp;
 82     return query(y,rt<<1|1,x);
 83 }
 84 
 85 int main(){
 86    while(~scanf("%d",&n)){
 87       xx.clear();Map.clear();
 88       for(int i=0;i<n;i++){
 89          scanf("%s%d%d",OP[i].str,&OP[i].x,&OP[i].y);
 90          OP[i].add();
 91       }
 92      sort(xx.begin(),xx.end());
 93      xx.erase(unique(xx.begin(),xx.end()),xx.end());
 94      int len=xx.size();
 95      for(int i=0;i<len;i++)
 96         Map[xx[i]]=i;
 97      build(0,len-1,1);
 98       for(int i=0;i<n;i++){
 99         if(OP[i].str[0]=='a')
100             insert(Map[OP[i].x],OP[i].y,1);
101         else if(OP[i].str[0]=='r')
102             remove(Map[OP[i].x],OP[i].y,1);
103         else {
104             Node ans=query(OP[i].y+1,1,Map[OP[i].x]+1);
105             if(ans.l==-1)printf("-1\n");
106             else
107                 printf("%d %d\n",xx[ans.l],ans.r);
108         }
109       }
110    }
111 }
View Code

posted on 2014-07-17 15:00  天依蓝  阅读(220)  评论(0编辑  收藏  举报

导航