题目

https://codeforces.com/problemset/problem/38/G

题意:

一些人按顺序进入队列,每个人有两个属性,地位$A$和能力$C$

每个人进入时都在队尾,并最多可以和前一位互换$C$次,如果前一位的地位高于自己,则无法继续互换.

最终一次性输出整个队列

题解:

splay维护动态的队列

可以用类似权值线段树的思维去考虑

对于每个点,保存其子节点的最大值,自身的值,与子树的大小

对于每次插入时,若能跨过整颗右子树与当前节点,则向左走,否则向右

可以保证整个子树中序遍历的顺序即为当前队列

又因为是平衡树,每次插入一个点,都将该点旋转至根,因此均摊复杂度$O(logn)$

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;
const int maxn=1e6+10,maxm=2e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
class splaytree{
#define nd node[now]
#define ndl node[node[now].son[0]]
#define ndr node[node[now].son[1]]
public:
struct splaynode{
int son[2],pre;
int val,mx,size;
splaynode(){mx=val=size=pre=son[0]=son[1]=0;}
splaynode(int x,int fa=0){mx=val=x;pre=fa;son[0]=son[1]=0;size=1;}
};
int cnt,root;
vector<splaynode> node;
void pushup(int now){
nd.mx=nd.val,nd.size=1;
rep(i,0,1)if(nd.son[i]) {
nd.mx=max(node[nd.son[i]].mx,nd.mx);
nd.size+=node[nd.son[i]].size;
}
}
void pushdown(int now){}
void rotate(int now,int d){
int fa=nd.pre;
pushdown(fa);pushdown(now);
node[fa].son[!d]=nd.son[d];
node[nd.son[d]].pre=fa;
if(node[fa].pre){
node[node[fa].pre].son[node[node[fa].pre].son[1]==fa]=now;
}else root=now;
nd.pre=node[fa].pre;
nd.son[d]=fa,node[fa].pre=now;
pushup(fa);pushup(now);
}
void splay(int now,int dst){
pushdown(now);
while(nd.pre!=dst){
if(node[nd.pre].pre==dst)rotate(now,node[nd.pre].son[0]==now);
else{
int fa=nd.pre,d=(node[node[fa].pre].son[0]==fa);
if(node[fa].son[d]==now){rotate(now,!d);rotate(now,d);}
else {rotate(fa,d);rotate(now,d);}
}
}
if(!dst) root=now;
pushup(now);
}
void insert(int val,int len){
if(!root){
node[++cnt]=splaynode(val);
root=cnt;
return;
}
int now=root;
int flag=(val<(max(nd.val,ndr.mx))||len<ndr.size+1);
while(1){
if(!nd.son[flag]){
node[++cnt]=splaynode(val,now);
nd.son[flag]=cnt;
break;
}
if(!flag)len-=ndr.size+1;
now=nd.son[flag];
flag=(val<(max(nd.val,ndr.mx))||len<ndr.size+1);
}
pushup(now);
splay(cnt,0);
}
void print(){print(root);}
void print(int now){
if(nd.son[0]) print(nd.son[0]);
cout<<now<<' ';
if(nd.son[1]) print(nd.son[1]);
}
splaytree(int n){
node.resize(n+7);
root=0,cnt=0;
}
};
int main() {
IO;
cin>>n;
splaytree tree(n);
rep(i,1,n){
int a,b;cin>>a>>b;
tree.insert(a,b);
}
tree.print();
return 0;
}

codeforces 38G - Queue splay伸展树的更多相关文章

  1. Splay伸展树学习笔记

    Splay伸展树 有篇Splay入门必看文章 —— CSDN链接 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 创造者:Daniel Sleator 和 Robert Ta ...

  2. 【学时总结】◆学时·VI◆ SPLAY伸展树

    ◆学时·VI◆ SPLAY伸展树 平衡树之多,学之不尽也…… ◇算法概述 二叉排序树的一种,自动平衡,由 Tarjan 提出并实现.得名于特有的 Splay 操作. Splay操作:将节点u通过单旋. ...

  3. Codeforces 675D Tree Construction Splay伸展树

    链接:https://codeforces.com/problemset/problem/675/D 题意: 给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值 题解: ...

  4. Splay 伸展树

    废话不说,有篇论文可供参考:杨思雨:<伸展树的基本操作与应用> Splay的好处可以快速分裂和合并. ===============================14.07.26更新== ...

  5. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  6. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

  7. UVA 11922 Permutation Transformer —— splay伸展树

    题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘 ...

  8. [算法] 数据结构 splay(伸展树)解析

    前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...

  9. Codeforces 38G Queue 伸展树

    题目链接:点击打开链接 题意: 给定n个人来排队 每一个人有2个參数.身份优先级和脸皮厚度 == 来的那个人会排到队尾 假设这个人的优先级比他前面那个人的优先级大就会和前面那个人交换位置. 交换一次脸 ...

随机推荐

  1. Mac下显示网页全屏快捷键

    control+command+F mac下谷歌浏览器全屏时隐藏头部:(隐藏标签页和地址栏) command+shift+B

  2. zookeeper的Java端API应用

    1. 基本使用 org.apache.zookeeper.Zookeeper是客户端入口主类,负责建立与server的会话.它提供了表1所示几类主要方法: 功能 描述 create 在本地目录树中创建 ...

  3. openstack服务启动之nova-compute

    在openstack中,消息的传递一共有两种方式,分别是:服务之间的传递调用Restful api,服务中模块之间的传递使用消息队列.每一个模块在启动是都会启动消息队列,等待队列中的有消息到来.所以模 ...

  4. 无法推动项目起步?Let's try McDonald’s Theory

    McDonald’s Theory I use a trick with co-workers when we’re trying to decide where to eat for lunch a ...

  5. docker 系列 - 企业级私有镜像仓库Harbor部署(转载)

     本文转载自 搜云库 的文章 https://www.jianshu.com/p/7d76850de03f  , 感谢作者 3.png 上一篇文章搭建了一个具有基础功能,权限认证.TLS 的私有仓库, ...

  6. Vertica系列:性能优化

    Vertica 性能非常好, 平时基本不会碰到性能问题, 即使碰到, 优化也很容易, 而且效果往往会很好. ======================优化工具==================== ...

  7. java 用PDFBox 删除 PDF文件中的某一页

    依赖: <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox-app ...

  8. Android手机特殊软件配置

    1. 安装360一键root http://root.360.cn/ 2.安装SSHdroid 用于启用手机的ssh 地址:https://www.apk20.com/apk/77332/v/7346 ...

  9. Mybatis中#{}和${}传参的区别及#和$的区别小结

    最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, 比如说用#{},和 ${}传参的区别, 使用#传入参数是,sql语句解析是会加上"&quo ...

  10. gcd 二进制/循环

    #include<bits/stdc++.h> #define LL long long using namespace std; inline aabs(LL x){ ?x:-x;} i ...