给你一个笛卡尔坐标系,现在要支持三种操作,第一种操作是添加一个点(x,y),第二种操作是删除一个点(x,y), 第三种操作是查询严格在点(x,y)右上角的点中,横坐标最小的点,如果有多个点,选择纵坐标最小的那个。
--------
首先肯定离散化
然后考虑怎么用线段树表示二维的信息,觉得树套树也可以写,但是线段树套set更好写一点
以x为下标建立线段树,对每个叶子节点开一个set,表示x点有多少个y。
添加和查找只要递归到叶节点删去/增加就可以了
查找的话,要求严格在(x,y)右上
转化为代数也就是在(x+1,maxn)上找一个最小的下标满足该下标能顶到的最大值>y;
最小下标只要优先递归左子树就能满足;
找到后在set内upper_bound即可;
#include<bits/stdc++.h> #define ls (rt<<1) #define rs (rt<<1|1) #define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; const int maxn=4e5+5; int n; int op[maxn],x[maxn],y[maxn],lisan[maxn<<1]; struct seg{ int l,r,mx; }t[maxn<<2]; set<int>s[maxn<<2]; void push_up(int rt){ t[rt].mx=max(t[ls].mx,t[rs].mx); } void build(int rt,int l,int r){ t[rt].l=l;t[rt].r=r; if(l==r){ t[rt].mx=-1; return; } int mid=(l+r)>>1; build(ls,l,mid);build(rs,mid+1,r); } void update(int rt,int l,int r,int val,int type){ //cout<<rt<<" "<<t[rt].l<<" "<<t[rt].r<<" "<<l<<" "<<r<<" "<<val<<" "<<type<<endl; if(l<=t[rt].l&&t[rt].r<=r){ // update if(type==0){ s[rt].erase(val); if(s[rt].empty()) t[rt].mx=-1; else t[rt].mx=*s[rt].rbegin(); } else { s[rt].insert(val); t[rt].mx=*s[rt].rbegin(); } return; } if(t[ls].r>=l) update(ls,l,r,val,type); if(t[rs].l<=r) update(rs,l,r,val,type); push_up(rt); } int Ansx=0; int query(int rt,int l,int r,int y){ //cout<<":: "<<rt<<" "<<t[rt].l<<" "<<t[rt].r<<" "<<l<<" "<<r<<" "<<y<<" "<<t[rt].mx<<endl; if(l>r) return 0; if(l<=t[rt].l&&t[rt].r<=r){ if(t[rt].mx<=y) return 0; } if(t[rt].l==t[rt].r){ if(t[rt].mx<=y) return 0; else { Ansx=t[rt].l; return *s[rt].upper_bound(y); } } int ans=0; if(t[ls].r>=l&&t[ls].mx>y) ans=query(ls,l,r,y); if(ans) return ans; if(t[rs].l<=r&&t[rs].mx>y) ans=query(rs,l,r,y); return ans; } int cnt=0; int id(int x){ return lower_bound(lisan+1,lisan+cnt+1,x)-lisan; } int main(){ //freopen("lys.in","r",stdin); fastio; cin>>n; for(int i=1;i<=n;i++){ string s; cin>>s; if(s[0]=='a') op[i]=1; if(s[0]=='f') op[i]=2; cin>>x[i]>>y[i]; lisan[++cnt]=x[i]; lisan[++cnt]=y[i]; } sort(lisan+1,lisan+cnt+1); cnt=unique(lisan+1,lisan+cnt+1)-(lisan+1); build(1,1,cnt); for(int i=1;i<=n;i++){ if(op[i]==0){ //remove update(1,id(x[i]),id(x[i]),y[i],0); } else if(op[i]==1){ //add update(1,id(x[i]),id(x[i]),y[i],1); } else { //find int out=query(1,id(x[i])+1,cnt,y[i]); if(out==0) cout<<-1<<endl; else cout<<lisan[Ansx]<<" "<<out<<endl; } } }
标签:cnt,set,19,Codeforces,int,ls,ans,lisan From: https://www.cnblogs.com/liyishui2003/p/17162780.html