题目

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. 【学时总结】◆学时&#183;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. 通过 UDP 发送数据的简单范例

    package j2se.core.net.udp; import java.io.IOException;import java.net.DatagramPacket;import java.net ...

  2. IIS 部署WCF 4.0

    上一章节讲解如何新建WCF服务,此文讲解如何在IIS上发布,并能正常访问 本地部署IIS 首先在本机安装IIS,IIS如何勾选,哪些是必须的?不太清楚,有清楚的大牛请指正!目前我的基本配置如下: 配置 ...

  3. 树莓派系统安装、HDMI显示

    树莓派上可以安装多种操作系统,我们采用的是官方的基于debian的raspbian.系统安装方式见 安装完系统由于我使用的是7寸的HDMI屏,装完系统如果配置不该的话会导致右边有一部分无法显示,所以在 ...

  4. WebBrowser控件跨域访问页面内容

    原文出处 :http://blog.csdn.net/nocky/article/details/6056802 源码出处:http://www.codecentrix.com/blog/wnd2do ...

  5. 聊一聊Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

  6. phpcms2008常用函数小结

    {$head[title]} 页面标题,用法: <title>{$head[title]}-{$PHPCMS[sitename]}</title> {$PHPCMS[siten ...

  7. Git分支管理及常见操作

    众所周知,使用Git分支,我们可以从开发主线上分离开来,然后在不影响主线的同时继续工作. 既然要使用Git分支,这里就涉及到Git分支的管理及常见操作,如列出分支,分支的创建,分支的删除,分支的合并等 ...

  8. emWin视频播放器,含uCOS-III和FreeRTOS两个版本

    第10期:视频播放器配套例子:V6-918_STemWin提高篇实验_视频播放器(RTX版本,仅支持MDK4.74) 例程下载地址: http://forum.armfly.com/forum.php ...

  9. js——this

    每个函数的this是在调用时绑定的,完全取决于函数的调用位置 1. 绑定规则总结 一般情况下,按下列顺序从下至上来判断this的绑定对象(绑定的优先级从下至上递减) 默认:在严格模式下绑定到undef ...

  10. git强制提交本地分支覆盖远程分支

    git push origin 分支名 --force eg: cd 代码目录 git push origin master --force 运行结果: Total 0 (delta 0), reus ...