题目背景

这是一道经典的Splay模板题——文艺平衡树。

题目描述

您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入输出格式

输入格式:

第一行为n,m(n,m<=100000) n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,⋯n−1,n) m表示翻转操作次数

接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n1≤l≤r≤n

输出格式:

输出一行n个数字,表示原始序列经过m次变换后的结果

输入输出样例

输入样例

5 3
1 3
1 3
1 4
输出样例

4 3 2 1 5

splay模板题,维护该序列的中序遍历不变,然后每次通过旋转节点使操作的区间变作一颗字树,然后打上标记即可。
什么是splay?
一棵伸展树......
什么是伸展树?
最近刚学,我个人的理解,大概就是一个能在不破坏二叉搜索树结构(即中序遍历始终为升序)的情况下
通过旋转一个节点到他根节点位置使得操作区间恰好全部位于一棵子树内的方法。 然后就打上标记,之后在类似线段树一样的pushdown传递信息就好了。 代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define mod
#define mid (R+L>>1)
#define M 2000010
using namespace std;
LL read(){
LL nm=,oe=;char cw=getchar();
while(!isdigit(cw)) oe=cw=='-'?-oe:oe,cw=getchar();
while(isdigit(cw)) nm=nm*+(cw-''),cw=getchar();
return nm*oe;
}
LL n,m,l[M],r[M],tp[M],ad,sz[M],tg[M],ace,a,b,p,q,cnt;
bool flag=false;
void pushdown(LL x){
if(tg[x]==) return;
tg[x]=,swap(l[x],r[x]);
tg[l[x]]^=,tg[r[x]]^=;
}
void pushup(LL x){sz[x]=sz[l[x]]+sz[r[x]]+;}
LL build(LL L,LL R,LL rt){
if(L>R) return ;
tp[mid]=rt,sz[mid]=;
if(L==R) return L;
l[mid]=build(L,mid-,mid);
r[mid]=build(mid+,R,mid);
sz[mid]+=sz[l[mid]]+sz[r[mid]];
return mid;
}
void rotate(LL x){
if(ace==x) return;
LL top=tp[x];
pushdown(top),pushdown(x);
if(top==ace) ace=x,tp[x]=n+,tp[top]=x;
else{
if(l[tp[top]]==top) l[tp[top]]=x;
else r[tp[top]]=x;
tp[x]=tp[top],tp[top]=x;
}
if(l[top]==x) l[top]=r[x],tp[r[x]]=top,r[x]=top;
else r[top]=l[x],tp[l[x]]=top,l[x]=top;
pushup(top),pushup(x);
}
void oper(LL x){
if(x==ace||tp[x]==ace){return;}
LL top=tp[x];
pushdown(top);
if(tp[top]==ace) rotate(x);
else if(l[l[tp[top]]]==x||r[r[tp[top]]]==x) rotate(top);
else rotate(x);
}
LL find(LL x,LL pos){
pushdown(x);
if(sz[l[x]]==pos-) return x;
if(sz[l[x]]<pos-) return find(r[x],pos-sz[l[x]]-);
else return find(l[x],pos);
}
void ans(LL x){
if(x==) return;
pushdown(x);
ans(l[x]);
if(x<n&&x>){
if(flag) printf(" ");
flag=true;
printf("%lld",x-);
}
ans(r[x]);
}
int main(){
n=read()+,m=read(),ace=build(,n,n+);
while(m--){
a=read(),b=read();
p=find(ace,a),q=find(ace,b+);
while(tp[q]!=ace&&q!=ace) oper(q);
if(q!=ace) rotate(q);
while(tp[p]!=ace) oper(p);
tg[r[p]]^=;
}
ans(ace);
return ;
}

我这里还是写的比较模糊,我也是通过了解别人的博客才理解了splay

就是这个 -> http://blog.csdn.net/skydec/article/details/20151805

洛谷 P3391 【模板】文艺平衡树的更多相关文章

  1. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  2. 【洛谷P3391】文艺平衡树——Splay学习笔记(二)

    题目链接 Splay基础操作 \(Splay\)上的区间翻转 首先,这里的\(Splay\)维护的是一个序列的顺序,每个结点即为序列中的一个数,序列的顺序即为\(Splay\)的中序遍历 那么如何实现 ...

  3. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  4. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  5. 洛谷 P3391 模板Splay

    #include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...

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

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

  7. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

  8. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  9. 洛谷P3391文艺平衡树(Splay)

    题目传送门 转载自https://www.cnblogs.com/yousiki/p/6147455.html,转载请注明出处 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 ...

  10. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

随机推荐

  1. 深入理解计算机系统(4.1)------Y86指令集体系结构

    本章我们将进入处理器体系结构介绍的神秘海洋中,我们熟悉的手机,电脑等设备的核心硬件都离不开处理器.处理器可以称的上是人类创造的最复杂的系统之一,一块手指大小的硅片,可以容纳一个完整的高性能处理器.大的 ...

  2. Java设计模式(四)——再谈观察者模式

    在本系列的上一篇文章中,我们讨论了JDK对于观察者模式的一套实现.今天我们将要从另一个角度来探索Tomcat中是如何利用观察者模式加载各个组件.不过今天的任务不是解释Tomcat,所以我会单独把重点抽 ...

  3. struts2使用模型传值

    用户bean package userBeans; public class User { private String username; public String getUsername() { ...

  4. (七)php运算符

    一:算数运算符 +(加).-(减).*(成)./(除) %(取模,求余的意思) <?php $a=7/3; echo $a; //2.3333333333333.因为float类型的最大精度为1 ...

  5. Integrates Git with Sublime 3 to pull or push to Github by using Sublime plugin Git

    1. Git must be installed, Sublime plugin "Git" only connects Sublime with Git. Download UR ...

  6. MapReduce-实践1

      MR进阶实践1:  -file 分发多个文件 [-file 适合场景]分发文件在本地,小文件 -file分发原理         run.sh文件: 通过多个-file, 将多个本地文件分发到Ha ...

  7. 树莓派.安装系统+Node.js+MongoDB系列环境

    1.先去树莓派官网下载最新的ROM https://www.raspberrypi.org/downloads/raspbian/ 这里选的是: RASPBIAN JESSIE WITH DESKTO ...

  8. 12.21-Android ServerSocket

    建立ServerSocket服务器 1.new ServerSocket对象servierSocket 2.接收客户端请求Socket client = servierSocket.accept(); ...

  9. clone对象

    在JavaScript中,当对象作为参数传给函数的时候,在函数内部对这个对象的属性进行修改时,函数外部的对象属性也会跟着被修改,而有些时候我们并不想原来的对象数据发生改变,这时候就需要切断对象之间的引 ...

  10. CoreCLR源码探索(八) JIT的工作原理(详解篇)

    在上一篇我们对CoreCLR中的JIT有了一个基础的了解, 这一篇我们将更详细分析JIT的实现. JIT的实现代码主要在https://github.com/dotnet/coreclr/tree/m ...