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. ...
随机推荐
- Serializer组件
Serializer组件 一 .序列化器-Serializer 作用: 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 反序列化,把客户端发送过来的数据,经过req ...
- [洛谷P5367]【模板】康托展开
题目大意:给定一个$n$的排列,求它在$n$的全排列中的名次 题解:康托展开,对于一个全排列,第$i$为有$n+1-i$种选择,用变进制数表示,这一位就是$n+1-i$进制.记排列中第$[1,i)$中 ...
- webapi初学项目(增删改查),webapi增删
wenapi做了一个从数据库增删改查的项目 webapi: 1.创建项目:visual C# —> ASP.NET MVC 4 web应用程序 模板—>web api; 2.注册路由: 路 ...
- Disruptor分布式id生成策略
需要的pom文件: <!-- 顺序UUID --> <dependency> <groupId>com.fasterxml.uuid</groupId> ...
- 7 批量查询mget、批量修改bulk
注意:当执行多条数据查询.增删改时,一定要用mget.bulk,提升性能,减少网络传输 mget 回顾:查询单个文档 GET /beauties/my/2 mget 查询多个文档: 不同 ...
- emacs手动安装、解决不能使用中文输入法
emacs的安装 emacs的下载,解压 wget http://mirrors.ustc.edu.cn/gnu/emacs/emacs-25.3.tar.gz tar -zxf emacs-25.3 ...
- flutter isolate demo
main.dart import 'package:flutter/material.dart'; import 'package:flutter_isolate/flutter_isolate.da ...
- JavaScript箭头函数中的this详解
前言 箭头函数极大地简化了this的取值规则. 普通函数与箭头函数 普通函数指的是用function定义的函数: var hello = function () { console.log(" ...
- 导出带图片的Excel——OOXML文件分析
需求: 普通js导出文件excel具有兼容性问题,通过js-xsl导出文件API未找到导出图片的方案,实例过少,因此针对07年后以.xlsx后缀的excel文件,通过修改后缀.zip参考文件模板来实现 ...
- layui 多个文件上传控件 整合缩减代码
// 图片上传 upload.render({ elem: '.upload-img' // 点击上传的按钮统一使用该类 ,url: "{:url('image/upload')}" ...