【题目链接】

点击打开链接

【算法】

本题是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 ; }

最新文章

  1. 喜大普奔,微软Microsoft JDBC Driver For SQL Server已发布到maven中央仓库
  2. 随机数是骗人的,.Net、Java、C为我作证
  3. 在ubuntu 15.04下安装VMware Tools
  4. HTML5自学笔记[ 10 ]简单的购物车拖拽
  5. oracle数据库数据导出和导入
  6. 配置Linux系统网卡连接网络
  7. vsphere client cd/dvd 驱动器1 正在连接
  8. Imatest 崩溃
  9. SilverLight搭建WCF聊天室详细过程[转]
  10. matplotlia应用
  11. kubernetes集群pod使用tc进行网络资源限额
  12. 批量操作RunTime之获取的Dic换成Model
  13. jQuery Address全站 AJAX 完整案例详解
  14. java的代理和动态代理简单测试
  15. 初探 Yii2 的测试模式 index-test.php
  16. set集合去重机制
  17. 几种任务调度的 Java 实现方法与比较 mark
  18. UIImageView 和 UIWebView 小结
  19. 双态运维分享之二: 服务型CMDB的消费场景
  20. 《关于安卓和IOS开发》

热门文章

  1. Codeforces 848B Rooter&#39;s Song(分类+模拟)
  2. Docker如何部署Python项目
  3. 4.JAVA语言基础部分&mdash;枚举与泛型
  4. ImportError: No module named _curses;Color support is disabled, python-curses is not installed.解决办法
  5. c++中c_str()函数
  6. docker下用keepalived+Haproxy实现高可用负载均衡集群
  7. HDU 2009 整除的尾数 题解
  8. 使用session来存储用户的登录信息
  9. 【c语言】二维数组中的查找,杨氏矩阵在一个二维数组中,每行都依照从左到右的递增的顺序排序,输入这种一个数组和一个数,推断数组中是否包括这个数
  10. 带GPG签名的Git tag