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个參数.身份优先级和脸皮厚度 == 来的那个人会排到队尾 假设这个人的优先级比他前面那个人的优先级大就会和前面那个人交换位置. 交换一次脸 ...
随机推荐
- centos 6.5 ruby环境安装
redis3.0以上支持集群,自带集群管理工具redis-trib.rb:在搭建集群前,安装ruby环境 ruby安装包下载 安装开发工具 1.命令:yum groupinstall "De ...
- Devexpress dll搜集
Devexpress一部分在全局dll中,需要分析缺哪些dll,有两种方式1.打包,安装时会自动提示 2.使用自带分析工具Assembly deployment tool
- Android中的分层----service 层,domain层,dao 层,action层等设计
service 层 服务层:直接为客户端提供的服务或功能.也是系统所能对外提供的功能. domain层 领域层:系统内的领域活动,存放实体. dao 层 持久层,DB操作都写在这里,数据访问对象,通过 ...
- build script和all projects作用和区别
buildscript中的声明是gradle脚本自身需要使用的资源.可以声明的资源包括依赖项.第三方插件.maven仓库地址等.而在build.gradle文件中直接声明的依赖项.仓库地址等信息是项目 ...
- html取消回车刷新提交
<form class="weui-search-bar__form" onsubmit="return false;"> <form cla ...
- JavaSE回顾及巩固的自学之路(三)——————所有语言的都存在的基本运算
在上一篇的博客中,我回顾到Java中的关键字,标识符等知识点,而今天这篇博文将回顾Java的,哦,不,不止Java,据本人了解,几乎在所有的语言中的基础阶段,都会存在这些运算,只是语法不一样而已. 今 ...
- 十七、文件和目录——minishell(1)
主函数运行要去读取从标准输入或终端上输入的整个命令行,然后再去解析命令行参数,解析出来之后,要将其封装成一个 program,然后再将 program 放入 job 中,然后再去执行 job 中的命令 ...
- 【python小练】0017-将xls文件内容写入xml文件中
第 0017 题: 将 第 0014 题中的 student.xls 文件中的内容写到 student.xml 文件中,如 下所示: <?xml version="1.0" ...
- DUMP1 企业级电商项目
系统:centos6 配置mirror阿里云 https://opsx.alibaba.com/mirror 远程管理首选:ssh 账户密码登录(ssh user@host) 或者 本地私钥连接服务器 ...
- Intelij IDEA 内置 sql gui
IDEA 内置 自带 SQL GUI 最大意义 会自动识别 domain 对象与数据表的关系,也可以通过 Database 的数据表直接生成 domain 对象等等. 第一步 打开数据库视图 Vie ...