【题目链接】

点击打开链接

【算法】

本题是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. PAT (Advanced Level) 1087. All Roads Lead to Rome (30)

    暴力DFS. #include<cstdio> #include<cstring> #include<cmath> #include<vector> # ...

  2. VisualSVN Server 导入已存在的库

    http://blog.csdn.net/lidatgb/article/details/7984220         早些时候建立过一个SVN Server的库,后来觉得库的名字太长了,随意换了一 ...

  3. 转:linux下ip修改与域名解析查看等

    转自: http://www.justwinit.cn/post/7038/ IP:     ifconfiggateway:172.16.0.254 [root@localhost ~]# nets ...

  4. People seldom do what they believe in. They do what is convenient, then repent.

    People seldom do what they believe in. They do what is convenient, then repent. 人们很少真正实践他们的理想.他们只做比较 ...

  5. invlpg 指令简单介绍

    invlpg 指令简单介绍 void tlb_invalidate(pde_t *pgdir, void *va) { // Flush the entry only if we're modifyi ...

  6. C语言-计数排序

    计数排序的基本思想是:统计一个数序列中小于某个元素a的个数为n,则直接把该元素a放到第n+1个位置上.当然当过有几个元素相同时要做适当的调整,因为不能把所有的元素放到同一个位置上.计数排序假设输入的元 ...

  7. 【POJ 1716】Integer Intervals(差分约束系统)

    id=1716">[POJ 1716]Integer Intervals(差分约束系统) Integer Intervals Time Limit: 1000MS   Memory L ...

  8. iOS--判断字符串NSString中数字、中文、大小写英文

    iOS--判断字符串NSString中数字.中文.大小写英文   <iframe id="iframeu2051914_0" src="http://pos.bai ...

  9. java设计模式----迭代器模式和组合模式

    迭代器模式: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 设计原则: 单一责任:一个类应该只有一个引起变化的原因 组合模式: 允许你将对象组合成树形结构来表现“整体/部分” ...

  10. [网页游戏开发]容器的使用及自定义Tab,RadioGroup,List,ViewStack

    Morn里面,容器和其他普通组件不同,无需皮肤,所以也不能从组件树种拖动创建(Tab,RadioGroup例外),只能转换而来 Morn的容器组件主要有Box,Container,Panel,Tab, ...