非旋treap模板
bzoj3580
非旋转treap
在大神教导下发现split一段区间时先split右边再split左边比较好写
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long LL;
const int M=200007;
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=0;
for(;isdigit(c);c=getchar())x=x*10-48+c;
return f?x:-x;
}
struct D{
int c[2];
D(){c[0]=c[1]=0;}
};
struct treap{
int sz,val,fix,mn,rev,tag,c[2];
void input(){
val=mn=rd();
fix=rand();
sz=1;
rev=tag=c[0]=c[1]=0;
}
}a[M];
int n,m,rt;
inline int min(int x,int y){
return x<y?x:y;
}
void update(int x){
a[x].mn=a[x].val,a[x].sz=1;
if(a[x].c[0]) a[x].mn=min(a[x].mn,a[a[x].c[0]].mn),a[x].sz+=a[a[x].c[0]].sz;
if(a[x].c[1]) a[x].mn=min(a[x].mn,a[a[x].c[1]].mn),a[x].sz+=a[a[x].c[1]].sz;
}
void totag(int x,int z){
a[x].tag+=z;
a[x].mn+=z;
a[x].val+=z;
}
void pushdown(int x){
if(a[x].rev){
if(a[x].c[0])a[a[x].c[0]].rev^=1;
if(a[x].c[1])a[a[x].c[1]].rev^=1;
a[x].rev^=1;
swap(a[x].c[0],a[x].c[1]);
}
if(a[x].tag){
if(a[x].c[0]) totag(a[x].c[0],a[x].tag);
if(a[x].c[1]) totag(a[x].c[1],a[x].tag);
a[x].tag=0;
}
}
int build(int l,int r){
if(l>r) return 0;
int mid=l+r>>1;
a[mid].c[0]=build(l,mid-1);
a[mid].c[1]=build(mid+1,r);
update(mid);
return mid;
}
D split(int x,int k){
D nw;
if(x==0)return nw;
pushdown(x);
if(a[a[x].c[0]].sz+1==k){
nw.c[1]=a[x].c[1];
a[x].c[1]=0;
nw.c[0]=x;
}
else if(k<=a[a[x].c[0]].sz){
nw=split(a[x].c[0],k);
a[x].c[0]=nw.c[1];
nw.c[1]=x;
}
else{
nw=split(a[x].c[1],k-a[a[x].c[0]].sz-1);
a[x].c[1]=nw.c[0];
nw.c[0]=x;
}
update(x);
return nw;
}
int merge(int x,int y){
if(!x) return y;
if(!y) return x;
if(a[x].fix<a[y].fix){
pushdown(x);
a[x].c[1]=merge(a[x].c[1],y);
update(x);
return x;
}
else{
pushdown(y);
a[y].c[0]=merge(x,a[y].c[0]);
update(y);
return y;
}
}
void add(int x,int y,int z){
D t2=split(rt,y);
D t1=split(t2.c[0],x-1);
totag(t1.c[1],z);
rt=merge(merge(t1.c[0],t1.c[1]),t2.c[1]);
}
void ins(int x,int z){
D tt=split(rt,x);
rt=merge(merge(tt.c[0],z),tt.c[1]);
}
void del(int x){
D t2=split(rt,x);
D t1=split(t2.c[0],x-1);
rt=merge(t1.c[0],t2.c[1]);
}
void get(int x,int y){
D t2=split(rt,y);
D t1=split(t2.c[0],x-1);
printf("%d\n",a[t1.c[1]].mn);
rt=merge(merge(t1.c[0],t1.c[1]),t2.c[1]);
}
void reverse(int x,int y){
D t2=split(rt,y);
D t1=split(t2.c[0],x-1);
a[t1.c[1]].rev^=1;
rt=merge(merge(t1.c[0],t1.c[1]),t2.c[1]);
}
void revolve(int x,int y,int z){
D t2=split(rt,y);
D t1=split(t2.c[0],x-1);
D tt=split(t1.c[1],z);
rt=merge(merge(merge(t1.c[0],tt.c[1]),tt.c[0]),t2.c[1]);
}
int main(){
int i,x,y,z;
char s[9];
n=rd();
for(i=1;i<=n;i++) a[i].input();
rt=build(1,n);
m=rd();
for(i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='A'){
x=rd(),y=rd(),z=rd();
add(x,y,z);
}
else if(s[0]=='I'){
x=rd();
a[++n].input();
ins(x,n);
}
else if(s[0]=='D'){
x=rd();
del(x);
}
else if(s[0]=='M'){
x=rd(),y=rd();
get(x,y);
}
else if(s[3]=='E'){
x=rd(),y=rd();
reverse(x,y);
}
else{
x=rd(),y=rd(),z=rd();
z=(z%(y-x+1)+(y-x+1))%(y-x+1);
z=(y-x+1)-z;
revolve(x,y,z);
}
}
return 0;
}
非旋treap模板的更多相关文章
- 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)
原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- 非旋 treap 结构体数组版(无指针)详解,有图有真相
非旋 $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ ...
- 2018.08.27 rollcall(非旋treap)
描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...
- 非旋Treap总结 : 快过Splay 好用过传统Treap
非旋$Treap$ 其高级名字叫$Fhq\ Treap$,既然叫$Treap$,它一定满足了$Treap$的性质(虽然可能来看这篇的人一定知道$Treap$,但我还是多说几句:$Fhp\ Treap$ ...
- 2827: 千山鸟飞绝 非旋treap
国际惯例的题面:看起来很不可做的样子,我们先来整理一下题意吧.就是,维护每个点曾经拥有过的最大的两个属性值,支持把点的位置移动.我们用map对每个位置进行离散化,对每个位置建立一个平衡树.为了方便分离 ...
- 2081.09.22 Kuma(非旋treap)
描述 有N张卡片,编号从0到n-1, 刚开始从0到n-1按顺序排好. 现有一个操作, 对于p. l,表示从第p张卡片之后的l张卡片拿到 最前面. 例如n=7的时候, 刚开始卡片序列为0 1 2 3 4 ...
- 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)
传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...
- 2018.08.05 bzoj3223: Tyvj 1729 文艺平衡树(非旋treap)
传送门 经典的平衡树问题,之前已经用splay写过一次了,今天我突发奇想,写了一发非旋treap的版本,发现挺好写的(虽然跑不过splay). 代码: #include<bits/stdc++. ...
随机推荐
- 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1936 Solved: 551[Submit][Status][Di ...
- NodeJS 爬虫爬取LOL英雄联盟的英雄信息,批量下载英雄壁纸
工欲善其事,必先利其器,会用各种模块非常重要. 1.模块使用 (1)superagent:Nodejs中的http请求库(每个语言都有无数个,java的okhttp,OC的afnetworking) ...
- 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(一)
Spring+MyBatis 首先要搭建的是Spring+MyBatis的整合框架,毕竟Spring是整个Web框架的核心部位,而数据库操作是一切测试的基础嘛. 目录结构 ━java ┣ contro ...
- dom 节点篇 ---单体模式
<script> var creatTag={ oUl:document.createElement('ul'), oDiv:document.createElement('div'), ...
- git文件迁移到新架构
环境: ubuntu16.04 代码托管地址:git.oschina.net 迁移原因: git上某工程是一堆静态页面html,因为在ubuntu下缺乏git图形客户端,想使用eclipse集成的gi ...
- nginx--->高并发优化
在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题. nginx配置文件和内核参数的优化,如有不妥,敬请指出 一.nginx的配置优化 1)nginx进程数 ...
- sqlserver 数据库索引建立原则
1.始终包含聚集索引 当表中不包含聚集索引时,表中的数据是无序的,这会降低数据检索效率.即使通过索引缩小了数据检索的范围,但由于数据本身是无序的,当从表中提取实际数据时,会产生频繁的定位问题,这也使得 ...
- Solr学习总结(八)IK 中文分词的配置和使用
最近,很多朋友问我solr 中文分词配置的问题,都不知道怎么配置,怎么使用,原以为很简单,没想到这么多朋友都有问题,所以今天就总结总结中文分词的配置吧. 有的时候,用户搜索的关键字,可能是一句话,不是 ...
- 堆排序分析及php实现
堆排序:是一种特殊形式的选择排序,他是简单选择排序的一种改进. 什么是堆? 具有n个元素的序列:{k1,k2,ki,…,kn} (ki <= k2i,ki <= k2i+1) 或者 (ki ...
- 参加SFDC的感触
今天参加了SFDC. 第一次参加这样的技术大会,感触总是有点. 简单的记录如下 1.自动化运维在行业已经成为趋势,未来DevOps 作为开发和运维统一已经是新时代对开发人员的要求.公司架构一个自己的自 ...