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 ...
随机推荐
- Vue 如何实现一个底部导航栏组件
参考网址: https://www.jianshu.com/p/088936b7b1bd/ Vue 如何实现一个底部导航栏组件 可以看到父组件是知道我点击了底部TabBar的哪个item的. 实现 实 ...
- qt 定义插件
定义的接口----------------------------------------------#ifndef REGEXPINTERFACE_H #define REGEXPINTERFACE ...
- C++泛型编程之类模板
泛型语义 泛型(Generic Programming),即是指具有在多种数据类型上皆可操作的含意.泛型编程的代表作品 STL 是一种高效.泛型.可交互操作的软件组件. 泛型编程最初诞生于 C++中, ...
- Maven解决依赖冲突
依赖冲突 若项目中多个Jar同时引用了相同的Jar时,会产生依赖冲突,但Maven采用了两种避免冲突的策略,因此在Maven中是不存在依赖冲突的. 短路优先 本项目-->A.jar-->B ...
- 从拟阵基础到 Shannon 开关游戏
从拟阵基础到 Shannon 开关游戏 本文中的定理名称翻译都有可能不准确!如果有找到错误的同学一定要联系我! 本文长期征集比较好的例题,如果有比较典型的题可以联系我 目录 从拟阵基础到 Shanno ...
- 【硬核摄影2.0】用线性CCD器件制作扫描相机
本文参考资料:[1] (Strongly Recommend!) Fundamentals and Experiments of Line Scan Camera: http://www.elm-ch ...
- ArrayList线程不安全怎么办?(CopyOnWriteArrayList详解)
ArrayList线程不安全怎么办? 有三种解决方法: 使用对应的 Vector 类,这个类中的所有方法都加上了 synchronized 关键字 就和 HashMap 和 HashTable 的关系 ...
- MediaWiki 语法简介
本文尚在完善中... 图片 图片官方教程 图文并茂的内容读起来总是更加舒服,让我们在wiki里引入图片. 内部图片 上传图片 点击右侧上传文件,上传文件后会获得文件名 编辑图片 文件上传后在编辑框,如 ...
- VS2017 添加预定义宏
project_name[right click] -> Properties -> C/C++ -> Preprocessor -> Preprocessor Definit ...
- Ansible基础使用
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 Ansible命令用法 1.1 免密钥 1.2 Ad-Hoc基础命令 1.3 ...