splay是支持区间操作的,先做这道题入个门

大多数操作都和普通splay一样,就不多解释了,只解释一下不大一样的操作

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
inline int read(){
int w=,f=;
char ch=getchar();
while(ch<''||ch>''){
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
w=(w<<)+(w<<)+ch-;
ch=getchar();
}
return w*f;
}
int n,m,tot,cnt,root;
struct node{
int ch[],sum,cnt,val,f,rev;//比普通平衡树多一个lazy tag
}st[];
inline void push_up(int p){
st[p].sum=st[st[p].ch[]].sum+st[st[p].ch[]].sum+st[p].cnt;
}
inline bool identify(int p){
return st[st[p].f].ch[]==p;
}
inline void connect(int x,int fa,int son){
st[x].f=fa;st[fa].ch[son]=x;return;
}
inline void rotate(int x){
int y=st[x].f;int z=st[y].f;
int yson=identify(x);int zson=identify(y);
int b=st[x].ch[yson^];
connect(b,y,yson);connect(y,x,(yson^));connect(x,z,zson);
push_up(y);push_up(x);return;
}
inline void splay(int x,int goal){
while(st[x].f!=goal){
int y=st[x].f;int z=st[y].f;
int yson=identify(x);int zson=identify(y);
if(z!=goal){
if(yson==zson) rotate(y);
else rotate(x);
}
rotate(x);
}
if(!goal) root=x;
return;
}
inline void insert(int x){
int now=root;int f=;
while(st[now].val!=x&&now){
f=now;
now=st[now].ch[x>st[now].val];
}
if(now){
st[now].cnt++;
}
else{
tot++;now=tot;
if(f){
st[f].ch[x>st[f].val]=now;
}
st[now].ch[]=st[now].ch[]=;
st[now].cnt=st[now].sum=;
st[now].val=x;st[now].f=f;
}
splay(now,);return;
}
inline void push_down(int p){
int ls=st[p].ch[];int rs=st[p].ch[];
if(st[p].rev){
swap(st[p].ch[],st[p].ch[]);
st[st[p].ch[]].rev^=;
st[st[p].ch[]].rev^=;
st[p].rev=;
}
}
inline void find(int x){
int now=root;if(!now) return;
while(st[now].val!=x&&st[now].ch[x>st[now].val]){
now=st[now].ch[x>st[now].val];
}
splay(now,);return;
}
inline int Next(int x,int f){
find(x);int now=root;
if(st[now].val<x&&!x) return now;
if(st[now].val>x&&x) return now;
now=st[now].ch[f];
while(st[now].ch[f^]) now=st[now].ch[f^];
return now;
}
inline int k_th(int x){
int now=root;
if(st[now].sum<x) return false;
while(true){
push_down(now);//在查找的时候记得下移标记
int ls=st[now].ch[];
if(x>st[ls].sum+st[now].cnt){
x-=st[ls].sum+st[now].cnt;
now=st[now].ch[];
}
else if(x<=st[ls].sum){
now=ls;
}
else return now;//这个地方把返回原值改成返回位置
}
}inline void rev(int l,int r){
int x=k_th(l-);int y=k_th(r+);
splay(x,);splay(y,x);
st[st[y].ch[]].rev^=;
}//翻转的操作就是将l-1转到根上,r+1转到根的右儿子,然后l到r这个区间就是根右儿子的左儿子(比较绕,可以画个图想一想
inline void output(int p){
push_down(p);
if(st[p].ch[]) output(st[p].ch[]);
if(st[p].val>=&&st[p].val<=n) printf("%d ",st[p].val);
if(st[p].ch[]) output(st[p].ch[]);
}//输出的时候下推一下标记,输出顺序就是二叉树的顺序
int main(){
n=read();m=read();int i,j,k;
insert(INF);insert(-INF);
for(i=;i<=n;i++){
insert(i);
}
while(m--){
int x,y;x=read();y=read();
rev(x+,y+);
}
output(root);
return ;
}

文艺平衡树 lg3391(splay维护区间入门)的更多相关文章

  1. bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2202  Solved: 1226[Submit][Sta ...

  2. 【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 N,M<= ...

  3. splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)

    先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...

  4. P3391 【模板】文艺平衡树(Splay)新板子

    P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转 ...

  5. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...

  6. 洛谷 P3391 【模板】文艺平衡树(Splay)

    题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

  7. 洛谷 P3391【模板】文艺平衡树(Splay)

    题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

  8. 文艺平衡树(Splay)

    题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

  9. 洛谷P3391 【模板】文艺平衡树(Splay)(FHQ Treap)

    题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

随机推荐

  1. 打印机打印pdf文件特别慢怎么解决

    PDF等文件中都包含了一些或者很多光栅化数据(图片.嵌入的字体等).这些文件在打印时,打印机驱动程序都会在系统中生成大量EMF文件(增强型变换文件),小到1MB,大到500MB,过大的EMF临时文件会 ...

  2. memcached的安装、常用命令以及在实际开发中的案例

    Memcached注意缺乏安全认证以及安全管制需要将Memcached服务器放置在防火墙(iptables)之后 Linux平台 (CentOS)安装Memcached 安装依赖yum -y inst ...

  3. oracle基础知识点

    一.count(*).count(1).count(字段名)的区别select count(*) from t_md_inst --153797 --包含字段为null 的记录select count ...

  4. canvas-画圆心的算法

    公式为x=16sin~3t,y=(13cost-5cos2t-2cos3t-cos4t) x+r(16Math.pow(Math.sin(t),3)) y-r(13Math.cos(t)-5Math. ...

  5. MST Unification CodeForces - 1108F

    #include<iostream> #include<cstring> #include<algorithm> using namespace std; ; in ...

  6. 题解【AcWing272】最长公共上升子序列

    题面 一道线性 DP 好题. 设 \(dp_{i,j}\) 表示在所有 \(a_{1\dots i}\),\(b_{1\dots j}\) 的子序列中,以 \(b_j\) 结尾的最长公共上升子序列的最 ...

  7. linux 搭建python虚拟环境

    requirements.txt 包含paramiko,pysfp.setuptools,适用python版本3.6.6+ 前提编译安装python wget wget https://www.pyt ...

  8. DFS-回溯与剪枝-C - N皇后问题

    C - N皇后问题 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.你的任务是,对于给定的N,求出有多少种合法的放 ...

  9. 微信小程序 --- 日历效果

    wxml部分: <view class='box1' style='width: {{ sysW * 7 }}px'> <view class='dateBox'>{{ yea ...

  10. ipa文件信息检查工具

    项目地址:https://github.com/ryjwinner/softwares/raw/master/iOS-checkIPA.jar 项目简介: 针对近期大量iOS app需要签名,但多家签 ...