正题

题目链接: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】的更多相关文章

  1. 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)

    在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...

  2. 15天玩转redis —— 第六篇 有序集合类型

    今天我们说一下Redis中最后一个数据类型 “有序集合类型”,回首之前学过的几个数据结构,不知道你会不会由衷感叹,开源的世界真好,写这 些代码的好心人真的要一生平安哈,不管我们想没想的到的东西,在这个 ...

  3. Treap入门(转自NOCOW)

    Treap 来自NOCOW Treap,就是有另一个随机数满足堆的性质的二叉搜索树,其结构相当于以随机顺序插入的二叉搜索树.其基本操作的期望复杂度为O(log n). 其特点是实现简单,效率高于伸展树 ...

  4. Treap和名次树

    Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体.BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添 ...

  5. Java 集合系列 12 TreeMap

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  6. SPOJ 3273 - Order statistic set , Treap

    点击打开链接 题意: 集合S支持一下四种操作:   INSERT(S,x) :   假设S中没有x,则插入x DELETE(S,x):  假设S中有x,则删除x K-TH(S):           ...

  7. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

  8. bzoj1208 [HNOI2004]宠物收养所(STL,Treap)

    1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5956  Solved: 2317[Submit][Sta ...

  9. bzoj1588 [HNOI2002]营业额统计(Treap)

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 11485  Solved: 4062[Submit][Sta ...

随机推荐

  1. Jmeter 生成测试报告、Jenkins 配置

    1. Jmeter 生成测试报告  示例: jmeter -n -t test.jmx -l result.jtl -e -o ./report 成功执行并生成报告: 生成报告失败:注意报告存放目录或 ...

  2. jQuery中的文档操作处理(五):append()、prepend()、after()、before()、wrap()、wrapAll()、wrapInner()、clone()等

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  3. jQuery中的子(后代)元素过滤选择器(四、六):nth-child()、first-child、last-child、only-child

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  4. jQuery中的属性过滤选择器(四、五):[attribute] 、[attribute=value]、[attribute!=value] 、[attribute^=value] 等

    <!DOCTYPE html> <html> <head> <title>属性过滤选择器</title> <meta http-equ ...

  5. 微信小程序学习笔记五 常见组件

    1. 常见组件 重点讲解小程序中常用的布局组件 1.1 view 代替 原来的div标签 <!-- pages/index/index.wxml --> <view hover-cl ...

  6. 常见面试题:java8有什么新特性?

    常见面试题:java8有什么新特性? 主要有以下这些新特性: lambda 表达式,经常配合函数式接口使用,可以有效减少代码量 Runnable 是一个函数式接口,下面展示了创建线程三种写法,显然最后 ...

  7. Redis(三):新数据类型

    配置文件redis.conf详解 bind=127.0.0.1 # 表示只能在本机中访问redis,将该行注释掉,即可接收任何IP地址的访问 protected-mode # 设置为no,表示关闭保护 ...

  8. 自己写一个Map

    Map的实现其实很简单,一个key对应一个value就行 . 本Map是写着玩的,是想告诉初学者我们也可以写一个简单的Map来自己用 代码: public class MyMap<K, V> ...

  9. zabbix告警推送至个人微信

    文章原文 自从接触zabbix后,就一直想着怎么才能把告警推送到个人微信上.有这样的想法主要是个人微信的使用频率远远要比钉钉,企业微信,邮箱,飞书等使用频率要高.比如我,就遇到过在周末的时候,因为没有 ...

  10. HTML一小时入门,半天掌握

    还没有写完,后续持续更新 首先来熟悉一下html的基本结构 <!DOCTYPE HTML> <html> <head> <meta charset=" ...