【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标记表示是否翻转 ------------------------------------------------- ...
随机推荐
- eopkg命令
#命令: add-repo (ar) ---添加存储库 blame (bl) ---包所有者和发布信息 build (bi) ---建立eopkg包 check ---验证安装 clean ...
- python decode unicode encode
字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(en ...
- 一点点VIM
VIM 当你喜欢它时,你会发现真的不错,不过配置真是麻烦, 不过万事开头难,当你熟练时真的会发现她的美. syntax on set nu colo evening set mouse=a set c ...
- TFS2018 获取所有Build变量及变量值
添加一个Command Line 步骤,Tool设置为 cmd ,并设置参数为 /k set 注意:若在执行时出现如下报错信息,Tool的值改成 cmd.exe --20T02::.0416435Z ...
- jquery 禁用/启用滚动条
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- linux操作系统下查看某rpm包是32bit 还是x64bit的命令
[root@hosta ~]# rpm -qa --queryformat "%{NAME}-%{VERSION}-%{RELEASE} (%{ARCH})\n" | grep l ...
- 在linux中安装.sh 文件
有一些linux的安装包是.sh后缀的安装包,可以通过$bash xxx.sh的命令来进行安装.
- 【dotnet跨平台】"dotnet restore"和"dotnet run"都做了些什么?
[dotnet跨平台]"dotnet restore"和"dotnet run"都做了些什么? 前言: 关于dotnet跨平台的相关内容.能够參考:跨平台.NE ...
- 如何动态地给vSphere虚拟机模板注入信息
在做vSphere自动化安装过程中,遇到这样一个需求:将vCenter Server做成模板,在给用户自动化装好vSphere后, 下载vCenter Server模板并启动虚拟机,然后将vCente ...
- 《从零開始学Swift》学习笔记(Day 61)——Core Foundation框架之内存管理
原创文章,欢迎转载. 转载请注明:关东升的博客 在Swift原生数据类型.Foundation框架数据类型和Core Foundation框架数据类型之间转换过程中,尽管是大部分是能够零开销桥接,零开 ...