【题目链接】

点击打开链接

【算法】

本题是splay区间操作的模板题

我们每个点的权值设为”当前在序列中的排名“,根据二叉排序树的性质,这棵树的中序遍历就是当前序列

如果我们要获得一段区间[l,r],那么我们将l-1splay到根节点,将r+1splay到根节点的右子树的根,我们发现,根节点

的右节点的左子树就是区间[l,r]

对于翻转操作,我们其实只需将“根节点的右节点的左子树”这棵树不断地进行左右子树交换就可以了,但是,为了避免

交换次数太多,我们可以像线段树那样,每个点都存一个懒惰标记

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000 int i,N,M,l,r; template <typename T> inline void read(T &x) {
int f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} template <typename T> inline void write(T x) {
if (x < ) { putchar('-'); x = -x; }
if (x > ) write(x/);
putchar(x%+'');
} template <typename T> inline void writeln(T x) {
write(x);
puts("");
} struct Splay {
int root,total;
struct Node {
int size,val,son[],fa;
bool rev;
} Tree[MAXN+];
inline bool get(int x) {
return Tree[Tree[x].fa].son[] == x;
}
inline void update(int index) {
Tree[index].size = Tree[Tree[index].son[]].size + Tree[Tree[index].son[]].size + ;
}
inline void build(int index,int l,int r) {
int mid = (l + r) >> ;
Tree[index].rev = false;
Tree[index].val = mid;
Tree[index].size = ;
if (l == r) return;
if (l <= mid - ) {
++total;
Tree[index].son[] = total;
Tree[total].fa = index;
build(total,l,mid-);
Tree[index].size += Tree[Tree[index].son[]].size;
}
if (mid + <= r) {
++total;
Tree[index].son[] = total;
Tree[total].fa = index;
build(total,mid+,r);
Tree[index].size += Tree[Tree[index].son[]].size;
}
}
inline void rotate(int x) {
int f = Tree[x].fa,g = Tree[f].fa,
tmpx = get(x),tmpf = get(f);
if (Tree[f].rev) pushdown(f);
if (Tree[x].rev) pushdown(x);
if (!f) return;
Tree[f].son[tmpx] = Tree[x].son[tmpx^];
if (Tree[x].son[tmpx^]) Tree[Tree[x].son[tmpx^]].fa = f;
Tree[x].son[tmpx^] = f;
Tree[f].fa = x;
Tree[x].fa = g;
if (g) Tree[g].son[tmpf] = x;
update(f);
update(x);
}
inline void splay(int x) {
int f;
for (f = Tree[x].fa; (f = Tree[x].fa); rotate(x))
if (Tree[f].fa) rotate(get(x) == get(f) ? f : x);
root = x;
}
inline void splayII(int x) {
int f;
for (f = Tree[x].fa; (f = Tree[x].fa) != root; rotate(x)) {
if (Tree[f].fa != root) rotate(get(x) == get(f) ? f : x);
}
}
inline void pushdown(int index) {
swap(Tree[index].son[],Tree[index].son[]);
Tree[Tree[index].son[]].rev ^= ;
Tree[Tree[index].son[]].rev ^= ;
Tree[index].rev = ;
}
inline int query_pos(int x) {
int index = root;
while (true) {
if (Tree[index].rev) pushdown(index);
if (x <= Tree[Tree[index].son[]].size) index = Tree[index].son[];
else {
x -= Tree[Tree[index].son[]].size;
if (x == ) return index;
--x;
index = Tree[index].son[];
}
}
}
inline int query_val(int x) {
int pos = query_pos(x);
return Tree[pos].val;
}
inline void reverse(int l,int r) {
int x = query_pos(l-),
y = query_pos(r+);
splay(x); splayII(y);
Tree[Tree[Tree[root].son[]].son[]].rev ^= ;
}
} T; int main() { read(N); read(M); T.total = ;
T.root = ;
T.build(,,N+); while (M--) {
read(l); read(r);
T.reverse(l+,r+);
} for (i = ; i <= N + ; i++) {
if (i == ) write(T.query_val(i)-);
else { putchar(' '); write(T.query_val(i)-); }
}
putchar(' '); puts(""); return ; }

【BZOJ 3223】 文艺平衡树的更多相关文章

  1. [题解]bzoj 3223 文艺平衡树

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

  2. bzoj 3223 文艺平衡树 - Splay

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

  3. BZOJ 3223 文艺平衡树 [codevs3303翻转区间]

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3223 通道2:http://codevs.cn/problem/3303/ 题目分析: 我 ...

  4. bzoj 3223 文艺平衡树 splay 区间翻转

    Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17715  Solved: 7769[Submit][Status][ ...

  5. BZOJ 3223 文艺平衡树

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

  6. bzoj 3223 文艺平衡树 Splay 打标志

    是NOI2003Editor的一个子任务 #include <cstdio> #include <vector> #define maxn 100010 using names ...

  7. [bzoj3224]普通平衡树/3223文艺平衡树

    这是一道很普通的题.. 最近花了很多时间来想要去干什么,感觉自己还是太拿衣服 做这道题是因为偶尔看到了lavender的blog和她的bzoj早期AC记录,就被题目深深地吸引到了,原因有二: 自己sp ...

  8. 3223. 文艺平衡树【平衡树-splay】

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

  9. BZOJ 3223: Tyvj 1729 文艺平衡树

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

  10. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

    速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...

随机推荐

  1. Linux 的信号和线程

    什么是线程 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成,每一个程序都至少 ...

  2. 真的了解CDN服务吗?

    Im CDN,WOW,COOL CDN知识详解 全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络,CDN是构建在网络之上的 ...

  3. Ubuntu下使用UFW配置防火墙(简化iptables的操作)

    UFW全称为Uncomplicated Firewall,是Ubuntu系统上配置iptables防火墙的工具.UFW提供一个非常友好的命令用于创建基于IPV4,IPV6的防火墙规则. 但是,UFW是 ...

  4. windows 下QT5.5+vs2013开发环境搭建

    开发环境搭建: 1.下载QT,下载的网址如下: http://download.qt.io/official_releases/vsaddin/ http://download.qt.io/offic ...

  5. 10分钟学会前端工程化(webpack4.0)

    一.概要 1.1.前端工程化 随着前端的不断发展与壮大,前端变得越来越复杂,组件化.模块化.工程化.自动化成了前端发展中不可或缺的一部分,具体到前端工程化,面临的问题是如何提高编码->测试-&g ...

  6. python把日期转换为秒数;日期转为字符串;datetime、date

    1.秒数是相对于1970.1.1号的秒数 2.日期的模块有time.datetime 3. import datetime t = datetime.datetime(2009, 10, 21, 0, ...

  7. linux 进程间通信之 消息队列

    消息队列就是一个消息的链表. 能够把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程能够向中依照一定的规则加入新消息.有读权限的进程则能够读走消息. 读走就没有了.消息队列是 ...

  8. 集成CCFlow工作流与GPM的办公系统驰骋CCOA介绍(三)

    通过组织结构能够对项目的岗位.部门.人员进行增删改操作. 加入新部门.并为新部门加入人员: 选中部门后,点击鼠标右键,能够选择加入平级部门或下属部门. 新建部门时,须要给部门设置部门编号.名称.与部门 ...

  9. groovy入门 第05章 基本输入输出

    基本输入输出 5.1基本输出 print XXX    //同一行输出 println XXX //换行输出 输出字符串: def message ="My name is Michael& ...

  10. 性能问题案例02——sybase连接堵塞问题

    现象:近期现场反馈一个问题.系统在审批的时候,常常卡死.整个系统全然用不了,浏览器訪问处于loading的状态. 排查: 1.一般系统挂了首先想到内存问题,可是现象是loading,也就是说没有挂,线 ...