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 "); 106 else 107 printf("%d %d ",xx[ans.l],ans.r); 108 } 109 } 110 } 111 }