[bzoj3223]文艺平衡树——splay
题意
你应当编写一个数据结构,支持以下操作:
- 反转一个区间
题解
我们把在数组中的位置当作权值,这样原序列就在这种权值意义下有序,我们考虑使用splay维护。
对于操作rev[l,r],我们首先把l-1 splay 到根,再把r+1 splay 到根的右子树的根,那么根的右子树的左子树就是区间[l,r]。
显然,这样会用到l-1和r+1。我们考虑添加两个哨兵节点,分别是1和n+2,[1,n]的值再分别加一就好了。
另外,为了防止过多的swap,我们延续线段树中的做法, 打一个lazy标记。与线段树不同的是,由于splay的拓扑结构经常会变化,所以每访问到一个节点,都要下传lazy标记。
注意build的写法。
代码
#include <bits/stdc++.h>
using namespace std;
int n, m, sz, rt;
#ifdef DEBUG
const int maxn = 100;
#else
const int maxn = 100005;
#endif
int fa[maxn], c[maxn][2], id[maxn];
int size[maxn];
bool rev[maxn];
void pushup(int k) {
int l = c[k][0], r = c[k][1];
size[k] = size[l] + size[r] + 1;
}
void pushdown(int k) {
int &l = c[k][0], &r = c[k][1];
if (rev[k]) {
swap(l, r);
rev[l] ^= 1;
rev[r] ^= 1;
rev[k] = 0;
}
}
void zig(int x, int &k) { // do one zig
int y = fa[x], z = fa[y], l, r; // y:father z:grandfather
if (c[y][0] == x) { // zig
l = 0;
} else
l = 1; // zag
r = l ^ 1;
if (y == k)
k = x; // single zig
else { // update grandfather
if (c[z][0] == y)
c[z][0] = x; // zig-zig
else
c[z][1] = x;
}
fa[x] = z;
fa[y] = x;
fa[c[x][r]] = y;
c[y][l] = c[x][r];
c[x][r] = y;
pushup(y);
pushup(x);
}
void splay(int x, int &k) {
while (x != k) {
int y = fa[x], z = fa[y];
if (y != k) {
if (c[y][0] == x ^ c[z][0] == y) // diff:zig-zag or zag-zig
zig(x, k);
else // same:zig-zig or zag-zag
zig(y, k);
}
zig(x, k);
}
}
int find(int k, int rank) {
pushdown(k);
int l = c[k][0], r = c[k][1];
if (size[l] + 1 == rank)
return k;
else if (size[l] >= rank)
return find(l, rank);
else
return find(r, rank - size[l] - 1);
}
void rever(int l, int r) {
int x = find(rt, l), y = find(rt, r + 2);
splay(x, rt);
splay(y, c[x][1]);
int z = c[y][0];
rev[z] ^= 1;
}
void build(int l, int r, int f) { // f:last node
if (l > r)
return;
int now = id[l], last = id[f];
if (l == r) {
fa[now] = last;
size[now] = 1;
if (l < f)
c[last][0] = now;
else
c[last][1] = now;
return;
}
int mid = (l + r) >> 1;
now = id[mid];
build(l, mid - 1, mid);
build(mid + 1, r, mid);
fa[now] = last;
pushup(mid);
if (mid < f) {
c[last][0] = now;
} else
c[last][1] = now;
return;
}
int main() {
#ifdef DEBUG
freopen("input", "r", stdin);
#endif
scanf("%d %d", &n, &m);
for (int i = 1; i <= n + 2; i++)
id[i] = ++sz;
build(1, n + 2, 0);
rt = (n + 3) >> 1;
for (int i = 1; i <= m; i++) {
int l, r;
scanf("%d %d", &l, &r);
rever(l, r);
}
for (int i = 2; i <= n + 1; i++) {
printf("%d ", find(rt, i) - 1);
}
return 0;
}
[bzoj3223]文艺平衡树——splay的更多相关文章
- BZOJ3223 文艺平衡树(splay)
题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
- JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树
http://172.20.6.3/Problem_Show.asp?id=1998 平衡树区间翻转的板子,重新写一遍,给自己码一个板子. #include<iostream> #incl ...
- [bzoj3223]文艺平衡树(splay区间反转模板)
解题关键:splay模板题. #include<cstdio> #include<cstring> #include<algorithm> #include< ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- BZOJ3223: Tyvj 1729 文艺平衡树 [splay]
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3595 Solved: 2029[Submit][Sta ...
- bzoj3223 文艺平衡树 (treap or splay分裂+合并)
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 3313 Solved: 1883 [Submit][S ...
- Tyvj P1729 文艺平衡树 Splay
题目: http://tyvj.cn/p/1729 P1729 文艺平衡树 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 此为平衡树系列第二道:文艺平衡树 ...
- BZOJ 3223: Tyvj 1729 文艺平衡树(splay)
速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...
随机推荐
- 我所认识的XPath
实例demo 测试demo所需要xml测试数据 <?xml version="1.0" encoding="iso-8859-1"?> <bo ...
- html5判断设备的动作
相应的事件 deviceorientation事件提供设备的物理方向信息,表示为一系列本地坐标系的旋角. devicemotion事件提供设备的加速信息,表示为定义在设备上的坐标系中的卡尔迪坐标.其还 ...
- mybatis <collection>标签 类型为string时无法获取重复数据错误
1.场景: fyq_share_house 表 和 fyq_sh_tag 表 两张表是一对多的关系, 一个楼盘对应多个标签,在实体类ShareHouse中使用 /** * 楼盘标签 */ privat ...
- C++学习006-条件运算符
这里我也理解的不咋的,大致意思应该就是根据运算符号 的优先级不同来解决的 条件运算符是其中一部分,而条件运算符具有右结合性,当一个表达式中出现多个条件运算符时,应该将位于最右边的问号与理他最近的冒号配 ...
- js中DOM 节点的一些操作方法
什么是DOM DOM:文档对象模型.DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构.目的其实就是为了能让js操作html元素而制定的一个规范. DOM就是由节点组成的. 解析过程 ...
- Windows Server 2008 R2(x64) IIS7+PHP5(FastCGI)环境搭建
相关软件下载: 1.PHP下载地址: http://windows.php.net/downloads/releases/php-5.4.4-nts-Win32-VC9-x86.zip 如果是win2 ...
- 权值树状数组 HDU-2852 KiKi's K-Number
引入 权值树状数组就是数组下标是数值的数组,数组存储下标对应的值有几个数 题目 HDU-2852 KiKi's K-Number 题意 几种操作,p=0代表push:将数值为a的数压入盒子 p=1代表 ...
- winform timer时间间隔小于执行时间
如果SetTimer的时间间隔为t,其响应事件OnTimer代码执行一遍的时间为T,且T>t.这样,一次未执行完毕,下一次定时到,这时候程序会如何执行? 可能的情况:1.丢弃还未执行的代码,开始 ...
- 入口文件-npm run dev
如果你是用vue.js官网提供的脚手架工具并沿用默认配置的话,你执行npm run dev的时候会出来页面,是因为你根目录下的package.json文件里script配置了"dev&quo ...
- el-checkbox根据是否被选中执行不同的操作
直接给el-checkbox绑定点击事件是没有效果的,因为它会被解析成其他形式的html,el-checkbox只是一个类名,因此,使用ts和jquery动态绑定事件: mounted() { $(& ...