YbtOJ#652-集合比较【Treap】
正题
题目链接:http://www.ybtoj.com.cn/problem/652
题目大意
定义一个元素为一个有序集合包含两个元素\(C=\{A,B\}\)
集合\(C=\{A,B\}\)的大小以\(A\)为第一关键字,\(B\)为第二关键字比较大小。
开始有两个元素\(S=\{S,S\},T=\{T,T\}\)且\(S<T\)。
然后\(n\)次加入一个新的由两个之前的元素依次组成的新元素,求出现过的元素小于等于它的有多少个。
\(1\leq n\leq 5\times 10^4\)
解题思路
如果递归比较是\(O(n)\)的显然不行,但是我们比较新的元素和旧的元素大小的时候如果我们可以知道以前元素的大小关系就可以快速比较(因为新的元素由旧的元素组成)
所以相当于我们要动态维护大小关系,因为要插入好像只能用平衡树。
然后要在树上查询两个点的大小关系,因为你要在平衡树上边移动边查询,所以不能用查询的时候结构会改变的平衡树(\(Splay\)之类的),正解是替罪羊的,反正这里用了\(Treap\)。
比较大小的时候直接在\(Treap\)上暴力跳找\(LCA\)就好了,深度是\(log\)级别的,然后不能动态维护深度所以有点麻烦
时间复杂度\(O(n\log^2 n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=51000;
int n,qfn,tot,a[N],b[N],p[N],v[N];
int t[N][2],siz[N],cnt[N],dat[N],fa[N];
int cmp(int x,int y){
++qfn;
if(x==y)return 2;
while(x){
if(fa[x]==y)
return t[y][0]==x;
v[x]=qfn;
x=fa[x];
}
while(y){
if(v[fa[y]]==qfn)
return t[fa[y]][1]==y;
y=fa[y];
}
return 0;
}
int cap(int x,int y){
int tmp=cmp(a[x],a[y]);
if(tmp!=2)return tmp;
return cmp(b[x],b[y]);
}
void PushUp(int x){
siz[x]=siz[t[x][0]]+siz[t[x][1]]+cnt[x];
return;
}
void zig(int &x){
int y=t[x][0];
t[x][0]=t[y][1];fa[t[y][1]]=x;
t[y][1]=x;fa[y]=fa[x];fa[x]=y;x=y;
PushUp(t[x][1]);PushUp(x);return;
}
void zag(int &x){
int y=t[x][1];
t[x][1]=t[y][0];fa[t[y][0]]=x;
t[y][0]=x;fa[y]=fa[x];fa[x]=y;x=y;
PushUp(t[x][0]);PushUp(x);return;
}
void Insert(int &x,int pos){
if(!x){
x=++tot;p[pos]=x;
a[tot]=a[pos];
b[tot]=b[pos];
cnt[x]=siz[x]=1;
dat[x]=rand();return;
}
int tmp=cap(pos,x),sum=0;
if(tmp==2){
p[pos]=x;cnt[x]++;
PushUp(x);return;
}
else if(tmp){
Insert(t[x][0],pos);fa[t[x][0]]=x;
if(dat[t[x][0]]>dat[x])zig(x);
}
else{
Insert(t[x][1],pos);fa[t[x][1]]=x;
if(dat[t[x][1]]>dat[x])zag(x);
}
PushUp(x);return;
}
int Query(int x){
int ans=siz[t[x][0]]+cnt[x];
while(x){
if(t[fa[x]][0]!=x)
ans+=siz[t[fa[x]][0]]+cnt[fa[x]];
x=fa[x];
}
return ans;
}
int main()
{
// freopen("comparison.in","r",stdin);
// freopen("comparison.out","w",stdout);
srand(19260817);
scanf("%d",&n);n++;
t[1][1]=n+1;
p[1]=1;a[1]=b[1]=1;
p[n+1]=n+1;a[n+1]=b[n+1]=n+1;
cnt[1]=cnt[n+1]=1;
fa[n+1]=tot=1;
PushUp(n+1);PushUp(1);
int rt=1;
for(int i=2;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
a[i]++;b[i]++;
a[i]=p[a[i]];b[i]=p[b[i]];
Insert(rt,i);
printf("%d\n",Query(p[i]));
}
return 0;
}
YbtOJ#652-集合比较【Treap】的更多相关文章
- 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)
在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...
- 15天玩转redis —— 第六篇 有序集合类型
今天我们说一下Redis中最后一个数据类型 “有序集合类型”,回首之前学过的几个数据结构,不知道你会不会由衷感叹,开源的世界真好,写这 些代码的好心人真的要一生平安哈,不管我们想没想的到的东西,在这个 ...
- Treap入门(转自NOCOW)
Treap 来自NOCOW Treap,就是有另一个随机数满足堆的性质的二叉搜索树,其结构相当于以随机顺序插入的二叉搜索树.其基本操作的期望复杂度为O(log n). 其特点是实现简单,效率高于伸展树 ...
- Treap和名次树
Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体.BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添 ...
- Java 集合系列 12 TreeMap
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- SPOJ 3273 - Order statistic set , Treap
点击打开链接 题意: 集合S支持一下四种操作: INSERT(S,x) : 假设S中没有x,则插入x DELETE(S,x): 假设S中有x,则删除x K-TH(S): ...
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- bzoj1208 [HNOI2004]宠物收养所(STL,Treap)
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5956 Solved: 2317[Submit][Sta ...
- bzoj1588 [HNOI2002]营业额统计(Treap)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 11485 Solved: 4062[Submit][Sta ...
随机推荐
- Spring详解(九)------事务管理
1.事务介绍 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 这里我们以取钱的例子来讲解:比如你去ATM ...
- 【C#】 堆和栈
前言 本文主要是讲解C#语言在内存中堆.栈的使用情况,使读者能更好的理解值类型.引用类型以及线程栈.托管堆. 首先感谢原文作者:Matthew Cochran 为我们带来了一篇非常好的文章,并配以大量 ...
- 图解Java 垃圾回收机制
摘要: Java技术体系中所提倡的 自动内存管理 最终可以归结为自动化地解决了两个问题:给对象分配内存 以及 回收分配给对象的内存,而且这两个问题针对的内存区域就是Java内存模型中的 堆区.关于对象 ...
- Java学习之 多态 Polymorphism
转自:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html 多态的概念 多态==晚绑定. 不要把函数重载理解为多态. 因为多态是一 ...
- Python也可以拥有延迟函数
延迟函数defer 我们知道在Golang中有一个关键字defer,用它来声明在函数调用前,会让函数*延迟**到外部函数退出时再执行,注意,这里的退出含义:函数return返回或者函数panic退出 ...
- netty系列之:搭建自己的下载文件服务器
目录 简介 文件的content-type 客户端缓存文件 其他HTTP中常用的处理 文件内容展示处理 文件传输进度 总结 简介 上一篇文章我们学习了如何在netty中搭建一个HTTP服务器,讨论了如 ...
- 发布日志 - kratos v2.0.4 版本发布
V2.0.4 Release Release v2.0.4 · go-kratos/kratos (github.com) 新的功能 proto-gen-http 工具在生产代码时如果 POST/PU ...
- Netty ServerBootstrap如何绑定端口
这篇讲netty服务端ServerBootstrap如何启动 前言 BootStrap在netty的应用程序中负责引导服务器和客户端.netty包含了两种不同类型的引导: 使用服务器的ServerBo ...
- Python脚本导出AWS EC2资源清单
环境需求 单位现在每隔一段时间需要核对一下 AWS 正在运行的 EC2 资源清单,为了避免核对失误以及重复性的工作,打算用脚本来解决这一重复性的工作.大概思路为 通过 AWS AK.SK 来索取 AW ...
- 【HMS Core 6.0全球上线】Toolkit,您的智能辅助编程好帮手
HMS Core 6.0已于7月15日全球上线.本次版本中,华为HMS Toolkit向广大开发者推出了智能辅助编程助手SmartCoder,帮助开发者轻松高效地集成HMS Core,开发新功能,创建 ...