CF19D Points 平衡树
题意:支持插入/删除点 $(x,y)$,查询一个点右上方横坐标与之最接近的点坐标.
我们可以对于每一个操作过的横坐标都开一个 $set$,然后再开一个平衡树,维护每个横坐标上最大的纵坐标.
然后查询点 $(x,y)$ 时就在平衡树查一下第一个横坐标大于 $x$,且最大值大于 $y$ 的就行了.
$splay$ 中有一些细节需要注意一下.
#include <set>
#include <map>
#include <cstdio>
#include <algorithm>
#define N 200005
#define inf 1200000005
#define lson p[x].ch[0]
#define rson p[x].ch[1]
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int tot,cnt,pp,root;
set<int>S[N];
map<int,int>idx,sp;
set<int>::iterator it;
struct data
{
int ch[2],f,maxx,val,id,size;
}p[N];
int newnode() { return ++tot; }
int get(int x) { return p[p[x].f].ch[1]==x; }
void pushup(int x)
{
p[x].maxx=p[x].val;
p[x].maxx=max(p[x].val,max(p[lson].maxx,p[rson].maxx));
p[x].size=p[lson].size+p[rson].size+1;
}
void rotate(int x)
{
int old=p[x].f,fold=p[old].f,which=get(x);
p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old;
p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold;
if(fold) p[fold].ch[p[fold].ch[1]==old]=x;
pushup(old),pushup(x);
}
void splay(int x,int &tar)
{
int fa,u=p[tar].f;
for(;(fa=p[x].f)!=u;rotate(x)) if(p[fa].f!=u) rotate(get(fa)==get(x)?fa:x);
tar=x;
}
void insert(int &x,int ff,int id,int v)
{
if(!x)
{
x=newnode();
p[x].id=id,p[x].val=v;
if(!sp[id]) sp[id]=++pp;
p[x].f=ff;
pushup(x);
}
else
{
insert(p[x].ch[id>p[x].id],x,id,v);
pushup(x);
}
}
int getr(int x)
{
while(rson) x=rson;
return x;
}
int getpre(int v)
{
int x=root,pre=root;
while(x)
{
if(p[x].id<=v) pre=x, x=rson;
else x=lson;
}
return pre;
}
int find(int x,int d)
{
if(p[lson].maxx>d) return find(lson,d);
else if(p[x].val>d) return p[x].id;
else return find(rson,d);
}
int main()
{
// setIO("input");
int i,j,n;
scanf("%d",&n);
p[0].maxx=-inf;
insert(root,0,-inf,-inf);
insert(root,0, inf,-inf);
for(i=1;i<=n;++i)
{
char str[10];
scanf("%s",str);
if(str[0]=='a')
{
int x,y;
scanf("%d%d",&x,&y);
if(!idx[x]) idx[x]=++cnt;
S[idx[x]].insert(-y);
int xx=-(*S[idx[x]].begin());
if(sp[x])
{
splay(sp[x], root);
p[root].val=xx;
pushup(root);
}
else
{
insert(root,0,x,y);
splay(tot,root);
// printf("%d\n",p[root].ch[1]);
}
}
if(str[0]=='r')
{
int x,y;
scanf("%d%d",&x,&y);
S[idx[x]].erase(-y);
if(S[idx[x]].empty())
{
splay(sp[x],root);
int L=getr(p[root].ch[0]);
int R=p[root].ch[1];
splay(L,p[root].ch[0]);
p[L].f=0, p[L].ch[1]=R, p[R].f=root=L;
pushup(L);
idx[x]=sp[x]=0;
}
else
{
splay(sp[x],root);
p[root].val=-(*S[idx[x]].begin());
pushup(root);
}
}
if(str[0]=='f')
{
int x,y;
scanf("%d%d",&x,&y);
int L=getpre(x);
splay(L,root);
if(p[p[root].ch[1]].maxx<=y) printf("-1\n");
else
{
int R=p[root].ch[1];
int xx=find(R,y);
int yy=idx[xx];
it=S[yy].lower_bound(-y);
if(it==S[yy].end()) it--;
while(*it>=-y) it--;
printf("%d %d\n",xx,-*it);
}
}
}
return 0;
}
CF19D Points 平衡树的更多相关文章
- [hdu4347]The Closest M Points(平衡树式kdtree)
解题关键:模板题(结合起来了) #include<iostream> #include<cstdio> #include<cstring> #include< ...
- CF 19D - Points 线段树套平衡树
题目在这: 给出三种操作: 1.增加点(x,y) 2.删除点(x,y) 3.询问在点(x,y)右上方的点,如果有相同,输出最左边的,如果还有相同,输出最低的那个点 分析: 线段树套平衡树. 我们先离散 ...
- CF 19D Points 【线段树+平衡树】
在平面上进行三种操作: 1.add x y:在平面上添加一个点(x,y) 2.remove x y:将平面上的点(x,y)删除 3.find x y:在平面上寻找一个点,使这个点的横坐标大于x,纵坐标 ...
- 【线段树】【CF19D】 Points
传送门 Description 在一个笛卡尔坐标系中,定义三种操作: \(add(x,y)\),将点\((x,y)\)标记在坐标系上 \(find(x,y)\),查询点\((x,y)\)严格右上方中, ...
- BZOJ 2733 HNOI 2012 永无乡 平衡树启示式合并
题目大意:有一些岛屿,一開始由一些无向边连接. 后来也有不断的无向边增加,每个岛屿有个一独一无二的重要度,问随意时刻的与一个岛屿联通的全部岛中重要度第k大的岛的编号是什么. 思路:首先连通性一定要用并 ...
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- BZOJ 2809 APIO 2012 dispatching 平衡树启示式合并
题目大意:给出一棵树,每个节点有两个值,各自是这个忍者的薪水和忍者的领导力.客户的惬意程度是这个点的领导力乘可以取得人数.前提是取的人的薪水总和不超过总的钱数. 思路:仅仅能在子树中操作.贪心的想,我 ...
- 有理数的稠密性(The rational points are dense on the number axis.)
每一个实数都能用有理数去逼近到任意精确的程度,这就是有理数的稠密性.The rational points are dense on the number axis.
- [LeetCode] Max Points on a Line 共线点个数
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...
随机推荐
- MySQL直方图
MySQL8.0开始支持索引之外的数据分布统计信息可选项 我们知道,在DB中,优化器负责将SQL转换为很多个不同的执行计划,完了从中选择一个最优的来实际执行.但是有时候优化器选择的最终计划有可能随着D ...
- golang内建容器
- WPF 程序如何跨窗口/跨进程设置控件焦点
原文:WPF 程序如何跨窗口/跨进程设置控件焦点 WPF 程序提供了 Focus 方法和 TraversalRequest 来在 WPF 焦点范围内转移焦点.但如果 WPF 窗口中嵌入了其他框架的 U ...
- Matlab图像处理基础知识
Matlab图像处理基础知识 Matlab的图片以矩阵的形式存储,矩阵的行列值为图片的行列的色彩值. 1图像表达方式: 像素索引 图像被视为离散单元.如使用I(2,2)可以获取第二行第二列的像素值 空 ...
- 从MVC -> MVVM ? 开发模式
MVVM 到底是什么? view :由 MVC 中的 view 和 controller 组成,负责 UI 的展示,绑定 viewModel 中的属性,触发 viewModel 中的命令: viewM ...
- CentOS - 查看操作系统版本
cat /etc/redhat-release 参考: https://www.cnblogs.com/baby123/p/6962398.html
- iOS配置TARGETS
说一下背景 自从这个项目不死不活的迭代了2年,从项目搭建到现在,一直都是自己在开发和维护,所以项目结构非常清晰,但是之前的水平写的代码现在看来也是惨不忍睹,不过本人比较懒,也就没有考虑过重构的事情 - ...
- 如何使用API的方式消费SAP Commerce Cloud的订单服务
最近Jerry在做一个微信和SAP Commerce Cloud集成的项目,需要在微信里调用后者的Restful API进行订单创建和读取.以前Jerry对SAP Commerce Cloud知之甚少 ...
- Lerp
Lerp,就是返回两个值之间的插值,一般有三个参数.第一个参数为初始值,第二个参数为最终值,插值为0~1d的一个浮点数值,为0时为初始值,1时为最终值,为0到1之间的数值时返回一个混合数值.若第三个参 ...
- 二十三、mysql索引管理详解
一.索引分类 分为聚集索引和非聚集索引. 聚集索引 每个表有且一定会有一个聚集索引,整个表的数据存储在聚集索引中,mysql索引是采用B+树结构保存在文件中,叶子节点存储主键的值以及对应记录的数据,非 ...