【BZOJ 3223】 文艺平衡树
【题目链接】
【算法】
本题是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】 文艺平衡树的更多相关文章
- [题解]bzoj 3223 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3884 Solved: 2235[Submit][Sta ...
- bzoj 3223 文艺平衡树 - Splay
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3884 Solved: 2235[Submit][Sta ...
- BZOJ 3223 文艺平衡树 [codevs3303翻转区间]
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3223 通道2:http://codevs.cn/problem/3303/ 题目分析: 我 ...
- bzoj 3223 文艺平衡树 splay 区间翻转
Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17715 Solved: 7769[Submit][Status][ ...
- BZOJ 3223 文艺平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 ...
- bzoj 3223 文艺平衡树 Splay 打标志
是NOI2003Editor的一个子任务 #include <cstdio> #include <vector> #define maxn 100010 using names ...
- [bzoj3224]普通平衡树/3223文艺平衡树
这是一道很普通的题.. 最近花了很多时间来想要去干什么,感觉自己还是太拿衣服 做这道题是因为偶尔看到了lavender的blog和她的bzoj早期AC记录,就被题目深深地吸引到了,原因有二: 自己sp ...
- 3223. 文艺平衡树【平衡树-splay】
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 ...
- BZOJ 3223: Tyvj 1729 文艺平衡树
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3628 Solved: 2052[Submit][Sta ...
- BZOJ 3223: Tyvj 1729 文艺平衡树(splay)
速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...
随机推荐
- Idea Failed to read artifact descriptor for xx:jar:unknown
网上的解决方案: 根据网上说明添加了maven命令clean compile install -Dmaven.test.skip=true,与我遇到的问题不同 有的方法猜测可以通过,但是没时间测试了 ...
- GeoServer发布Heatmap
转自原文 GeoServer发布Heatmap 百度等热力图是使用开源的heatmap.js做的,但是这种解决方案的缺陷是: 1 数据量大的话,从前端通过后台查询比较费时,比如arcserver默认设 ...
- 利用背景流量数据(contexual flow data) 识别TLS加密恶意流量
识别出加密流量中潜藏的安全威胁具有很大挑战,现已存在一些检测方法利用数据流的元数据来进行检测,包括包长度和到达间隔时间等.来自思科的研究人员扩展现有的检测方法提出一种新的思路(称之为“dataomni ...
- call lua function from c and called back to c
Just a simple example: --The c file: #include <stdio.h> #include "lua.h" #include & ...
- flex中dispatchEvent的用法(自定义事件) .
Evevt和EventDispatcher类在as3的事件机制中是很重要的角色,dispatchEvent()是EventDispatcher类的一个事件发送方法,它可以发送出Event类或其子类的实 ...
- Log4cpp 使用手册
参考资料: log4cpp 配置 与 使用http://www.cnblogs.com/welkinwalker/archive/2011/06/23/2088197.html 便利的开发工具-log ...
- 面向对象 委托变量和this的使用
委托方法: this的使用:
- ftk学习记(combox篇)
[声明:版权全部,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 上一篇文章谈到了多窗体,还是依照约定看一下效果是什么样的. 假设大家细心一点.就会发现窗体中的l ...
- [LeetCode] 038. Count and Say (Easy) (C++/Python)
索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 038. Cou ...
- Activity左边滑出,右边滑入的动画切换
Activity左边滑出,右边滑入的动画切换 转载请注明出处:http://blog.csdn.net/u012301841/article/details/46920809 大家都知道Android ...