[luogu P3391] 文艺平衡树

题目背景

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

题目描述

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

输入输出格式

输入格式:

第一行为n,m 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次变换后的结果。

输入输出样例

输入样例#1: 复制

5 3
1 3
1 3
1 4
输出样例#1: 复制

4 3 2 1 5

说明

n,m≤100000

上次就很想写了,splay的妙用。

splay能做到一般的平衡树做不到的东西——维护序列。

为什么一般的平衡树做不到?正是因为splaytree的核心操作——splay。

这个log级别的操作能将一个连续的子序列搞到一棵子树中。

比如要维护[l,r],则调用一下splay(find(l-1),0),splay(find(r+1),root)。

但是要注意一下,对于这题,我们需要一个节点在当前序列的排名和初始位置(即权值)。

一个节点的排名是它的左子树大小+1,初始位置是不变的。

对于这题,还有一个巧妙的地方,就是reverse操作。

这里用到了和线段树类似的lazy打标记,延迟下传的思想。还是很厉害的。

输出的话,根据二叉搜索树的性质,直接中序遍历。

code:

 #include <cstdio>
 #include <iostream>

 void OJ_file() {
     #ifndef ONLINE_JUDGE
         freopen("in.txt","r",stdin);
         freopen("out.txt","w",stdout);
     #endif
 }
 namespace fastIO {
     #define puc(c) putchar(c)
     inline int read() {
         ,f=; char ch=getchar();
         ') {
             if (ch=='-') f=-f;
             ch=getchar();
         }
         ') {
             x=(x<<)+(x<<)+ch-';
             ch=getchar();
         }
         return x*f;
     }
     ];
     template <class T> inline void write(T x) {
         ) {
             puc('); return;
         }
         ) x=-x,puc('-');
         ; x; x/=) w[++cnt]=x%;
         );
     }
     inline void newblank() {
         puc(' ');
     }
 } using namespace fastIO;

 int n,m;
 #define SplayTree node
 struct SplayTree {
     int v,k; bool r;
     node* c[];
     node () {
         v=k=r=;
         c[]=c[]=c[]=;
     }
 }*ro;
 void newnode (node* &x,int k) {
     x=,x->k=k;
 }
 void refresh (node* x) {
     x->v=;
     ]) x->v+=x->c[]->v;
     ]) x->v+=x->c[]->v;
 }
 void transfer (node* x) {
     if (x->r) {
         ]) x->c[]->r^=;
         ]) x->c[]->r^=;
         x->r=,std::swap(x->c[],x->c[]);
     }
 }
 #define M ((l)+(r)>>1)
 void setup (node* &x,int l,int r) {
     if (l>r) return;
     newnode(x,M);
     setup(x->c[],l,M-),setup(x->c[],M+,r);
     ]) x->c[]->c[]=x;
     ]) x->c[]->c[]=x;
     refresh(x);
 }
 bool dir (node* x) {
     ]) ;
     ]->c[]==x;
 }
 void linknode (node* y,node* x,bool p) {
     ]=y;
     if (y) y->c[p]=x;
 }
 void rotate (node* x) {
     ];
     linknode(y->c[],x,dir(y));
     linknode(y,x->c[p^],p);
     linknode(x,y,p^);
     refresh(y),refresh(x);
 }
 void splay (node* x,node* an) {
     ]==an) return;
     ]!=an) {
         ]->c[]==an) {
             rotate(x);
             if (!an) ro=x;
             return;
         }
         rotate(dir(x)^dir(x->c[])?x:x->c[]);
         rotate(x);
     }
     if (!an) ro=x;
 }
 node* find (node* x,int v) {
     transfer(x);
     ]?x->c[]->v:;
     if (v==s) return x;
     ) ],v);
     ],v-s-);
 }
 void reverse (int l,int r) {
     node* q[]={find(ro,l-),find(ro,r+)};
     splay(q[],),splay(q[],ro);
     ro->c[]->c[]->r^=;
 }
 void dfs (node* x) {
     transfer(x);
     ]) dfs(x->c[]);
     &&x->k<=n) {
         write(x->k),newblank();
     }
     ]) dfs(x->c[]);
 }
 int main() {
     OJ_file();
     n=read(),m=read(),ro=;
     setup(ro,,n+);
     int l,r;
     for (; m; --m) {
         l=read(),r=read();
         if (l==r) continue;
         reverse(l,r);
     }
     dfs(ro);
     ;
 }

[luogu P3391] 文艺平衡树的更多相关文章

  1. Luogu P3391 文艺平衡树(Splay or FHQ Treap)

    这道题要求区间反转...好东西.. 对于Splay:把l-1旋到根,把r+1旋到根的右儿子,这样r+1的左儿子就是整个区间了,然后对这个区间打个tg 注意要插-Inf和Inf到树里面,防止越界,坐标要 ...

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

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

  3. BZOJ3223/洛谷P3391 - 文艺平衡树

    BZOJ链接 洛谷链接 题意 模板题啦~2 代码 //文艺平衡树 #include <cstdio> #include <algorithm> using namespace ...

  4. P3391 文艺平衡树(Splay)

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

  5. 【Luogu】P3391文艺平衡树(Splay)

    题目链接 ddosvoid和自为风月马前卒教了我这道题 他们好强啊 如果我们要反转区间[l,r] 我们首先把l的前驱旋转到根节点 再把r的后继旋转到根节点的右儿子 那么此时根节点的右儿子的左儿子所代表 ...

  6. 洛谷 P3391 文艺平衡树

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

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

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

  8. P3391 文艺平衡树

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

  9. 【题解】P3391 文艺平衡树

    用pb_ds库中的rope水过去的,忽然发现这玩意能水好多模拟题. 详见这个博客:背景的小姐姐真的好看 声明 #include <ext/rope> using namespace __g ...

随机推荐

  1. Django session存储到redis数据库

    把session存储到redis数据库,需要在setting中配置 django-redis 中文文档 http://django-redis-chs.readthedocs.io/zh_CN/lat ...

  2. Redis学习-主从复制、哨兵

    主从复制 官方文档:https://redis.io/topics/replication Redis中的主从复制,也就是Master-Slave模型,有以下特点 Master可以拥有多个slave ...

  3. Linux笔记 #10# 用于支持Web应用开发&部署&配置的一些自定义脚本

    索引 一.本地开发与测试相关脚本 1.startup.sh 2.shutdown.sh 3.catalina-out.sh 4.localhost_access_log.sh 5.上传本地文件到服务器 ...

  4. 加域电脑登陆系统后桌面文件丢失,登录系统提示用户名为“Temp”。

    注册表中定位到“HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\ProfileList”, ...

  5. oracle SQL性能分析之10053事件

    优化器生成正确执行计划的前提条件是要有正确的统计信息,不准确的统计信息往往会导致错误的执行计划.当通过SQL和基数推断出的执行计划和实际执行计划不同时,就可以借助10053事件.10053事件是用来诊 ...

  6. 【题解】Luogu P4396 [AHOI2013]作业

    原题传送门 最快的解法好像是cdq,但窝只会莫队+线段树/树状数组的做法 题目要我们求1.在区间[l,r]中值域在[a,b]中有多少个数2.在区间[l,r]中值域在[a,b]中有多少个不同数 一眼就看 ...

  7. 【题解】Luogu P1471 方差

    原题传送门 简单进行推导之后,就能发现很妙的结论 用线段树维护区间和,区间平方和就珂以算出结果 #include <bits/stdc++.h> #define db double #de ...

  8. CMT302 Coursework Assessment Pro-forma

    Cardiff School of Computer Science and Informa5csCoursework Assessment Pro-formaModule Code: CMT302 ...

  9. AndroidStudio生成APK注意的几个问题

    生成APK遇到两个问题:一是生成的APK安装失败(没有勾选V1所致),二是生成APK后,百度与谷歌地图不显示(SHA1值改变所致). 通过Build>Generate Signed APK生成A ...

  10. web性能测试

    在公司Confluence上看到一篇好文,原链接已不能访问.先收藏 转帖自:http://blog.csdn.net/wxq8102/article/details/1735726 1.1基本概念并发 ...