codeforces 38G - Queue splay伸展树
题目
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伸展树的更多相关文章
- Splay伸展树学习笔记
Splay伸展树 有篇Splay入门必看文章 —— CSDN链接 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 创造者:Daniel Sleator 和 Robert Ta ...
- 【学时总结】◆学时·VI◆ SPLAY伸展树
◆学时·VI◆ SPLAY伸展树 平衡树之多,学之不尽也…… ◇算法概述 二叉排序树的一种,自动平衡,由 Tarjan 提出并实现.得名于特有的 Splay 操作. Splay操作:将节点u通过单旋. ...
- Codeforces 675D Tree Construction Splay伸展树
链接:https://codeforces.com/problemset/problem/675/D 题意: 给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值 题解: ...
- Splay 伸展树
废话不说,有篇论文可供参考:杨思雨:<伸展树的基本操作与应用> Splay的好处可以快速分裂和合并. ===============================14.07.26更新== ...
- [Splay伸展树]splay树入门级教程
首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...
- Splay伸展树入门(单点操作,区间维护)附例题模板
Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...
- UVA 11922 Permutation Transformer —— splay伸展树
题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘 ...
- [算法] 数据结构 splay(伸展树)解析
前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...
- Codeforces 38G Queue 伸展树
题目链接:点击打开链接 题意: 给定n个人来排队 每一个人有2个參数.身份优先级和脸皮厚度 == 来的那个人会排到队尾 假设这个人的优先级比他前面那个人的优先级大就会和前面那个人交换位置. 交换一次脸 ...
随机推荐
- java生产环境增量发版陷阱【原】
前言 在生产环境,我们为了降低发版风险,一般都只做增量发布,不做全量发布. 除非项目只有一到两人开发,对时间线和代码脉络结构一清二楚,才可全量发布. 然而增量发布也是有一定隐藏陷阱在里面的,以下就是笔 ...
- 理解maven命令package、install、deploy的联系与区别
我们在用maven构建java项目时,最常用的打包命令有mvn package.mvn install.deploy,这三个命令都可完成打jar包或war(当然也可以是其它形式的包)的功能,但这三个命 ...
- 项目thymeleaf
官方文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls 定义和引用片段 在我们的模板中,我们经常需 ...
- MVC的了解
MVC是一种架构模式,程序分层,分工合作,各层既相互独立,有协同工作. MVC:Model+View+Controller Model层:业务数据的信息表示,关注支撑业务的信息构成,通常是多个业务实体 ...
- 前端下拉框选择和动态生成调用div
进入到一个项目期中,一边做项目,一边学习其中用到的知识.这些知识都是零碎的,有数据库,有html,有js,还有django.趁周末时间,整理前面遇到过的前端相关的知识点. 下拉框选择 <html ...
- 上传文件服务与web服务分离
业务场景:1. 后端服务为java web应用,使用tomcat容器,多实例集群化部署.2. 前端使用nginx作为后端应用的反向代理. 业务需求:现在需要在java web应用端上传文件,同时还要能 ...
- ****** 三十 ******、软设笔记【计算机体系结构】-循环冗余校验码(CRC)
循环冗余校验码(CRC) 广泛地在网络通信及磁盘存储时采用. 1.多项式 在循环冗余校验(CRC)码中,无一例外地要提到多项式的概念.一个二进制数可以以一个多项式来表示.如1011表示为多项式X ...
- 20秒教你如何写maven2的pom文件的依赖包
所有Maven 库 需要的包 及 pom.xml 中 groupId artifactId version 都可在这个网上收到. 例如:需要 通过 maven 在项目 中 添加 geronimo-k ...
- 【LDAP】LDAP注入漏洞与防御
0x01 前言 前两天爆了一个LDAP漏洞,据说存在了8年现在才被发现,感概一下,不知这8年来有多少站被搞了... 想着复现这个漏洞,就先复习一下LDAP注入的相关知识吧,差了很多资料,记一下笔记. ...
- 【noip 2015】普及组
T1.金币 题目链接 #include<cstdio> #include<algorithm> #include<cstring> using namespace ...