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. Ubuntu18--使用vi编辑器方向键以及Backspace乱码问题

    解决方法一: 可以进入vi /etc/vim/vimrc.tiny目录对vim配置文件进行修改 修改内容: 修改完成就可以正常使用了.(换行的时候Esc退出编译状态,回车换行,输入第二句话,在按Esc ...

  2. 洛谷P1464 Function  HDU P1579 Function Run Fun

    洛谷P1464 Function HDU P1579 Function Run Fun 题目描述 对于一个递归函数w(a,b,c) 如果a≤0 or b≤0 or c≤0就返回值11. 如果a> ...

  3. Android开发第一天---AndroidStudio的安装和第一个安卓开发

    今天已经是开始学习Android的第二天,我居然才把AndroidStudio开发环境安装并配置好,我只能说“我太难了”,下了好几个版本,终于找到了一个合适的,得出一个结论外国的东西是真的不太好用啊, ...

  4. VUE项目编译和打包问题

    今天VPN不好使,所以准备看一下VUE前端的代码.因为是乙方新发过来的,所以想着先把代码跑起来.结果发现发过来的代码里没有node_modules. 解决方式 npm install express ...

  5. 【新人赛】阿里云恶意程序检测 -- 实践记录10.27 - TF-IDF模型调参 / 数据可视化

    TF-IDF模型调参 1. 调TfidfVectorizer的参数 ngram_range, min_df, max_df: 上一篇博客调了ngram_range这个参数,得出了ngram_range ...

  6. Redis的各个数据的类型基本命令

    什么是Redis: 概念: Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(key-value)数据库. 特征:1. 数据间没有必然的关联 ...

  7. 复习mongoose的基本使用

    mongodb参考 mongoose官网 mongoose用起来更便捷,更方便些

  8. tensor数据基操----索引与切片

    玩过深度学习图像处理的都知道,对于一张分辨率超大的图片,我们往往不会采取直接压平读入的方式喂入神经网络,而是将它切成一小块一小块的去读,这样的好处就是可以加快读取速度并且减少内存的占用.就拿医学图像处 ...

  9. 剑指offer-面试题16-数值的整数次方-数字

    /* 题目: 实现函数double Power(double base,int exponent), 求base的exponent次方. */ /* 思路: 本题需要考虑的情况较多: 1.0的负数次方 ...

  10. Linux connect: Network is unreachable

    在虚拟机中ping,发现网络不通: [root@node01 ~]# ping 114.114.114.114 connect: Network is unreachable 发生此问题时,环境如下: ...