单点更新 平面增减点后找出平面上坐标大于(x,y)的点,有多点则找x小y小
来源:互联网 发布:照片换发型软件 编辑:程序博客网 时间:2024/05/16 23:45
题意:有三种操作“add x y”往平面上添加(x,y)这个点,"remove x y",将平面上已经存在的点(x,y)删除,“find x y”找出平面上坐标严格大于(x,y)的点,如果有多个点找x最小的,再找y最小的。
第一次写这种类似的线段树,好处是省内存。
这里可以先读入所有坐标后去重,然后对于每一个x坐标,维护一个set记录该x坐标下的所有y坐标,便于添加点或者删除点后查找最大的y坐标。然后用线段树维护横坐标上的最大y坐标,便于快速查找。
#include <iostream>#include <cstdio>#include <cstring>#include <set>#include <map>#include <vector>#include <algorithm>using namespace std;#define LL(x) (x<<1)#define RR(x) (x<<1|1)const int N=2e5+5;vector<int> sx;map<int,int> imap;struct OP{char str[10];int x,y;void input(){scanf("%s%d%d",str,&x,&y);sx.push_back(x);}}op[N];struct Segtree{int imax[N*4];set<int> valu[N];void clear(){memset(imax,-1,sizeof(imax));for(int i=0;i<N;i++) valu[i].clear();}void add(int st,int ed,int ind,int x,int y){imax[ind]=max(imax[ind],y);if(st==ed) valu[x].insert(y);//注意这里是xelse{int mid=st+(ed-st)/2;if(x<=mid) add(st,mid,LL(ind),x,y);else add(mid+1,ed,RR(ind),x,y);}}void remove(int st,int ed,int ind,int x,int y){if(st==ed){valu[x].erase(y);imax[ind]=valu[x].empty()?-1:*(--valu[x].end());}else{int mid=st+(ed-st)/2;if(x<=mid) remove(st,mid,LL(ind),x,y);else remove(mid+1,ed,RR(ind),x,y);imax[ind]=max(imax[LL(ind)],imax[RR(ind)]);}}pair<int,int> find(int st,int ed,int ind,int x,int y){if(imax[ind]<y||ed<x) return make_pair(-1,-1);if(st==ed) return make_pair(st,*(valu[st].lower_bound(y)));else{int mid=st+(ed-st)/2;pair<int,int> tmp=find(st,mid,LL(ind),x,y);if(tmp.first!=-1) return tmp;return find(mid+1,ed,RR(ind),x,y);}}}seg;int main(){int n;while(scanf("%d",&n)!=EOF){sx.clear();imap.clear();seg.clear();for(int i=0;i<n;i++) op[i].input();sort(sx.begin(),sx.end());sx.erase(unique(sx.begin(),sx.end()),sx.end());int len=(int)sx.size()-1;for(int i=0;i<=len;i++) imap[sx[i]]=i;for(int i=0;i<n;i++){char ch=op[i].str[0];int x=op[i].x,y=op[i].y;if(ch=='a') seg.add(0,len,1,imap[x],y);else if(ch=='r') seg.remove(0,len,1,imap[x],y);else{pair<int,int> res=seg.find(0,len,1,imap[x]+1,y+1);if(res.first==-1) puts("-1");else printf("%d %d\n",sx[res.first],res.second);}}}return 0;}
0 0
- 单点更新 平面增减点后找出平面上坐标大于(x,y)的点,有多点则找x小y小
- CodeforcesBeta Round #19 D. Points(找出平面上坐标严格大于(x,y)的点)
- 平面上有一点(x,y),将其绕坐标原点旋转一角度α,求旋转后的点的坐标
- [Google] 平面上有很多点( x,y均为整数) ,求一个点 ,使该点到 所有点的 曼哈顿距离和 最小
- 输出一个平面点关于X轴Y轴以及原点的对称点
- 证明:(0,0)到(x,y)连线上横纵坐标都是正整数的点有gcd(x,y)个
- 已知两点和直线上的某点的Y值,求某点的x坐标
- 【转载】c++ API 在屏幕上(或窗口中)的(x,y)坐标绘制一个点
- js空间平面坐标变换(涉及文件读取,文本提取数字,特别是x,y点,以及html下拉框设计)
- AE开发,有几个点,已知X,Y坐标,如何在AxMapControl中显示这些点
- AutoCAD点排序(x坐标从小到大,y坐标从小到大)
- 设 P(x,y,z)是所求平面上任一点,则向量 AB=(-3,0,1),AP=(x-3,y,z), 因此平面的法向量为 n1=AB×AP=(-y,x+3z-3,-3y), 而 xoy 坐标面的法向量为
- 如何导出SHP文件中的点坐标(x,y)
- 平面上的点
- 【数学】给定两个点线性求解给定x坐标对应的y坐标值
- 关于解决这个问题:从一个点(x,y)绕另一个点(x0,y0)旋转任意角度A后得到的坐标(x1,y1)的坐标是多少?
- 矩形面积交 问题描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。
- 实时捕捉鼠标x点y点
- mybatis学习笔记之基础框架(2)
- Android 使用Android Studio进行NDK-JNI开发
- Failed to load the JNI shared Library (JDK)
- undo&redo&ibdata1---杂
- 动态代理
- 单点更新 平面增减点后找出平面上坐标大于(x,y)的点,有多点则找x小y小
- Kinect面部模型(2D)
- 比较系统版本
- Linux下配置https安全连接(ssl加密连接)
- Log4j2使用总结
- mybatis学习笔记之基础复习(3)
- UI-UITextField UIButton
- final 细节注意
- Android TV的音量键实现流程