写平衡树修锅快修到死系列

我太蠢了

其实是平衡树裸体裸题

插入,删除,交换前驱或后继,查询rank和kth

维护一个pos数组,表示第i个书的编号

然后注意许许多多的细节,没了

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Node{
int lson,rson,ran,val,w,sz;
}Treap[80000<<2];
int pos[80100],Lx,Rx,Nodecnt,n,m,root;
void pushup(int o){
Treap[o].sz=Treap[Treap[o].lson].sz+Treap[Treap[o].rson].sz+1;
}
void rotateR(int &o){
int k=Treap[o].lson;
Treap[o].lson=Treap[k].rson;
Treap[k].rson=o;
Treap[k].sz=Treap[o].sz;
pushup(o);
o=k;
}
void rotateL(int &o){
int k=Treap[o].rson;
Treap[o].rson=Treap[k].lson;
Treap[k].lson=o;
Treap[k].sz=Treap[o].sz;
pushup(o);
o=k;
}
int NewNode(int cx,int wl){
++Nodecnt;
Treap[Nodecnt].sz=1;
Treap[Nodecnt].lson=Treap[Nodecnt].rson=0;
Treap[Nodecnt].ran=rand();
Treap[Nodecnt].val=wl;
Treap[Nodecnt].w=cx;
return Nodecnt;
}
void insert(int &o,int cx,int wl){
if(!o){
o=NewNode(cx,wl);
return;
}
Treap[o].sz++;
if(wl<=Treap[o].val){
insert(Treap[o].lson,cx,wl);
if(Treap[Treap[o].lson].ran<Treap[o].ran)
rotateR(o);
// pushup(o);
}
else{
insert(Treap[o].rson,cx,wl);
if(Treap[Treap[o].rson].ran<Treap[o].ran)
rotateL(o);
// pushup(o);
}
}
void erase(int &o,int wl){
if(!o)
return;
if(Treap[o].val==wl){
if(Treap[o].lson==0||Treap[o].rson==0){
o=Treap[o].lson+Treap[o].rson;
return;
}
if(Treap[Treap[o].lson].ran<Treap[Treap[o].rson].ran){
rotateR(o);
erase(o,wl);
}
else{
rotateL(o);
erase(o,wl);
}
pushup(o);
return;
}
Treap[o].sz--;
if(wl<=Treap[o].val){
erase(Treap[o].lson,wl);
pushup(o);
}
else{
erase(Treap[o].rson,wl);
pushup(o);
}
}
int ranks(int o,int wl){
if(!o)
return 0;
if(wl==Treap[o].val){
return Treap[Treap[o].lson].sz+1;
}
if(wl<=Treap[o].val){
return ranks(Treap[o].lson,wl);
}
else{
return ranks(Treap[o].rson,wl)+Treap[Treap[o].lson].sz+1;
}
}
int kth(int k,int o){
if(k==0)
return 0;
if(k==Treap[Treap[o].lson].sz+1)
return Treap[o].w;
if(k<=Treap[Treap[o].lson].sz)
return kth(k,Treap[o].lson);
else
return kth(k-Treap[Treap[o].lson].sz-1,Treap[o].rson);
}
int pre(int wl){
return kth(ranks(root,wl)-1,root);
}
int back(int wl){
return kth(ranks(root,wl)+1,root);
}
int main(){
Lx=1;
// freopen("7.in","r",stdin);
// freopen("test.out","w",stdout);
srand(19260817);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
++Rx;
pos[x]=Rx;
insert(root,x,Rx);
}
char opt[20];
int sx,tx;
for(int i=1;i<=m;i++){
scanf("%s",opt);
if(opt[0]=='T'){
scanf("%d",&sx);
erase(root,pos[sx]);
Lx--;
pos[sx]=Lx;
insert(root,sx,Lx);
}
else if(opt[0]=='B'){
scanf("%d",&sx);
erase(root,pos[sx]);
Rx++;
pos[sx]=Rx;
insert(root,sx,Rx);
}
else if(opt[0]=='I'){
scanf("%d %d",&sx,&tx);
if(tx==0)
continue;
if(tx==1){
int need=back(pos[sx]);
erase(root,pos[sx]);
erase(root,pos[need]);
swap(pos[sx],pos[need]);
insert(root,sx,pos[sx]);
insert(root,need,pos[need]);
}
if(tx==-1){
int need=pre(pos[sx]);
erase(root,pos[sx]);
erase(root,pos[need]);
swap(pos[sx],pos[need]);
insert(root,sx,pos[sx]);
insert(root,need,pos[need]);
}
}
else if(opt[0]=='A'){
scanf("%d",&sx);
printf("%d\n",ranks(root,pos[sx])-1);
}
else if(opt[0]=='Q'){
scanf("%d",&sx);
printf("%d\n",kth(sx,root));
}
}
return 0;
}

p2596 书架(Treap)的更多相关文章

  1. 【Luogu】P2596书架(Splay)

    题目链接 通过这题我加深了对Splay的理解,原来Splay的子树也是可以接来接去接到别的点上的,而不是只能旋转qwq 具体接的办法就是swap大法. 对于Top操作我们把当前节点Splay到根,然后 ...

  2. splay tree 学习笔记

    首先感谢litble的精彩讲解,原文博客: litble的小天地 在学完二叉平衡树后,发现这是只是一个不稳定的垃圾玩意,真正实用的应有Treap.AVL.Splay这样的查找树.于是最近刚学了学了点S ...

  3. 洛谷 P2596 [ZJOI2006]书架 解题报告

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  4. P2596 [ZJOI2006]书架 && Splay 区间操作(三)

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  5. [洛谷P2596] [ZJOI2006]书架

    洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...

  6. [bzoj1861][Zjoi2006]Book 书架_非旋转Treap

    Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...

  7. fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架

    题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...

  8. P2596 [ZJOI2006]书架

    思路 一开始写fhq-treap 感觉越写越感觉splay好些,就去splay 然后维护序列 注意前驱后继的不存在的情况 但不用插入虚拟节点(那插入岂不太麻烦) 跑的真慢的一批,splay太多了 错误 ...

  9. P2596 [ZJOI2006]书架(splay)

    [题目链接] https://www.luogu.org/problemnew/show/P2596 平衡树,需支持五个操作: 1. 将某元素置顶:将元素旋到根,然后将左子树合并到该元素的后继 2. ...

随机推荐

  1. linux小倒腾

    1.vim安装,sudo apt-get install vim-gtk,于是vim就安装好了.当然在我电脑上还出现了gvim,简单的vim配置(etc/vim/vimrc): "我的设置 ...

  2. css实现文字太长,显示省略号

    /*显示为省略号*/ overflow:hidden;/*隐藏*/  white-space:nowrap;/*文本不进行换行*/text-overflow:ellipsis;/*省略号*/ /*强制 ...

  3. vue-cli 脚手架搭建

    1,下载node.js node.js 集成npm 管理器 2,打开命令行工具(win+R) node -v npm -v 出现对应版本号,则安装完成 3,配置代理信息 详见代理设定:https:// ...

  4. SQLServer 创建自己的数据库

    1)进入数据库服务器,创建自己的数据库 use master go create database Dt_Devtest on primary(name=[Dt_new_data],filename= ...

  5. Spring源码阅读(一)

    Spring通过配置文件或者注解对类实例进行加载管理.稍微思考,可以猜测spring加载过程肯定先把配置转化为统一的配置对象,再把通过配置对象生产类实例.阅读源码,我们也可以发现这个逻辑. sprin ...

  6. 设计模式之Singleton(单态)(转)

    定义: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作. 还有, singleton能够被状 ...

  7. javascript常用积累

    一.JS动画与动作不一致解决: if(!$( "#handle").is(":animated")){ //判断元素是否处于动画状态 } 二.停止事件冒泡 ev ...

  8. python 网页cookie的使用

    网页cookie的使用 Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) # opener的概念当你获取一个URL你使用一个opener(一 ...

  9. Python基础教程之udp和tcp协议介绍

    Python基础教程之udp和tcp协议介绍 UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但 ...

  10. redis 五大数据类型以及操作

    一.redis的两种链接方式 1.简单连接 import redis conn = redis.Redis(host='10.0.0.200',port=6379) conn.set('k1','年后 ...