BZOJ 3223: Tyvj 1729 文艺平衡树
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3628 Solved: 2052
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
1 3
1 3
1 4
Sample Output
HINT
N,M<=100000
Source
小生的第三道伸展树板子题。初识Splay维护区间翻转操作。引用一位前辈的题解。、
splay的经典操作:翻转区间-->交换左右子树,注意打标记降低翻转次数。如何找到要操作的区间[l,r]:将当前排名(size)为l-1 +1 的节点转到根,将当前排名为r+2的节点转到根的右子树的根节点,则根的右子树的根节点的左子树为所求区间,直接打标记就可以了。
#include <bits/stdc++.h> class Splay {
public:
Splay(void) {
root = NULL;
for (top = ; top < siz; ++top)
stk[top] = tree + top;
} inline void auto_build(int n) {
for (int i = ; i <= n + ; ++i)
insert(i);
} inline void insert(int val) {
if (root == NULL)
root = newnode(val, NULL);
else {
node *t = root;
while (t->son[] != NULL)
t = t->son[];
splay(t, NULL);
t->son[] = newnode(val, t);
update(root); splay(t->son[], NULL);
}
} inline void reverse(int l, int r) {
++l, ++r;
splay(rnk(l - ), NULL);
splay(rnk(r + ), root);
reverse(root->son[]->son[]);
} inline void print(int n) {
for (int i = ; i <= n; ++i)
printf("%d ", rnk(i + )->value);
}
private:
const static int siz = 1e5 + ; struct node {
int size;
int value;
bool reverse;
node *father;
node *son[];
}*root; node tree[siz], *stk[siz]; int top; inline node *newnode(int v, node *f) {
node *ret = stk[--top];
ret->size = ;
ret->value = v;
ret->father = f;
ret->son[] = NULL;
ret->son[] = NULL;
ret->reverse = false;
return ret;
} inline void freenode(node *t) {
stk[top++] = t;
} inline int size(node *t) {
return t == NULL ? : t->size;
} inline void update(node *t) {
t->size = ;
t->size += size(t->son[]);
t->size += size(t->son[]);
} inline bool son(node *f, node *s) {
if (f == NULL)return false;
return f->son[] == s;
} inline bool tag(node *t) {
return t == NULL ? false : t->reverse;
} inline void reverse(node *t) {
if (t != NULL)
t->reverse ^= true;
} inline void pushdown(node *t) {
if (tag(t)) {
std::swap(t->son[], t->son[]);
reverse(t->son[]);
reverse(t->son[]);
t->reverse ^= true;
}
} inline void connect(node *f, node *s, bool k) {
if (f == NULL)
root = s;
else
f->son[k] = s;
if (s != NULL)
s->father = f;
} inline void rotate(node *t) {
node *f = t->father;
node *g = f->father;
bool a = son(f, t), b = !a;
connect(f, t->son[b], a);
connect(g, t, son(g, f));
connect(t, f, b);
update(f);
update(t);
} inline void splay(node *t, node *p) {if (t)
while (t->father != p) {
node *f = t->father;
node *g = f->father;
pushdown(g);
pushdown(f);
pushdown(t);
if (g == p)
rotate(t);
else {
if (son(g, f) ^ son(f, t))
rotate(t), rotate(t);
else
rotate(f), rotate(t);
}
}
} inline node *find(int val) {
node *ret = root;
while (ret != NULL && ret->value != val)
pushdown(ret), ret = ret->son[val >= ret->value];
return ret;
} inline node *rnk(int kth) {
for (node *t = root; t; ) {
pushdown(t);
if (size(t->son[]) < kth) {
kth -= size(t->son[]);
if (kth == )
return t;
else
--kth, t = t->son[];
}
else
t = t->son[];
}
}
}S; signed main(void) {
int n, m; scanf("%d%d", &n, &m);
S.auto_build(n);
for (int i = , l, r; i <= m; ++i)
scanf("%d%d", &l, &r), S.reverse(l, r);
S.print(n);
}
@Author: YouSiki
BZOJ 3223: Tyvj 1729 文艺平衡树的更多相关文章
- BZOJ 3223: Tyvj 1729 文艺平衡树(splay)
速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...
- bzoj 3223: Tyvj 1729 文艺平衡树 (splay)
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3223 题面: 3223: Tyvj 1729 文艺平衡树 Time Limit: 10 S ...
- BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6881 Solved: 4213[Submit][Sta ...
- [BZOJ 3223 & Tyvj 1729]文艺平衡树 & [CodeVS 3243]区间翻转
题目不说了,就是区间翻转 传送门:BZOJ 3223 和 CodeVS 3243 第一道题中是1~n的区间翻转,而第二道题对于每个1~n还有一个附加值 实际上两道题的思路是一样的,第二题把值对应到位置 ...
- fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)
题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...
- bzoj 3223/tyvj 1729 文艺平衡树 splay tree
原题链接:http://www.tyvj.cn/p/1729 这道题以前用c语言写的splay tree水过了.. 现在接触了c++重写一遍... 只涉及区间翻转,由于没有删除操作故不带垃圾回收,具体 ...
- BZOJ 3223 Tyvj 1729 文艺平衡树(Splay)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3223 [题目大意] 给出一数列,问m次区间翻转后的结果. [题解] Splay 区间翻 ...
- BZOJ - 3223 Tyvj 1729 文艺平衡树 (splay/无旋treap)
题目链接 splay: #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f ...
- BZOJ 3223 Tyvj 1729 文艺平衡树 | Splay 维护序列关系
题解: 每次reverse(l,r) 把l-1转到根,r+1变成他的右儿子,给r+1的左儿子打个标记就是一次反转操作了 每次find和dfs输出的时候下放标记,把左儿子和右儿子换一下 记得建树的时候建 ...
随机推荐
- 安卓学习----使用okHttp(get方式)---下载图片
一首先下载Jar包 https://github.com/square/okhttp 如果使用android studio只需要加入依赖 compile 'com.squareup.okhttp3:o ...
- lable计算行高
_introduce.text=status.introduce; //设置行间距 NSMutableAttributedString *attributedString = [[NSMutableA ...
- python之局部变量引用赋值前的结果
通过正则表达式,实现加减 昨晚在做计算器的时候,被一个BUG搞懵比了.现在再看看,发现我好小白啊~~ #++- num = input("please input:") sa = ...
- git之四
1.管理修改 Git与其他版本控制系统相比,Git跟踪并管理的是修改,而非文件. 为什么说Git管理的是修改,而不是文件.接下来做测试,我们对readme.txt修改,追加一行内容: echo &qu ...
- this的作用--转载
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- JVM之SerialOld收集器
Serial收集器的老年代版本 单线程收集器 标记-整理算法 stop the world Client模式下的虚拟机使用 Server模式下,搭配Parallel Scavenge使用及CMS发生C ...
- cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。
#!/bin/bash #功能:让GBK编码的文件可以使用less正常显示中文(自动识别GBK和UTF-8编码) #v0. 在LINUX下,使用UTF-8编码,less UTF-8的文件时显示中文正常 ...
- 【转】What is an SDET? Part 2 – Skill Matrix of SDET
What is an SDET? Part 2 ---- Skill Matrix of SDET (Instead of naming it as part 2 of What is an SDET ...
- UNIX文件的权限之“设置用户ID位”
用stat函数可以获取一个文件的状态信息,原型是这样的: int stat(const char *path, struct stat *buf); 其中结构体stat的结构: struct stat ...
- LoadRunner录制Web协议的脚本 (by网络)
LoadRunner录制Web协议的脚本 http://itindex.net/detail/50530-loadrunner-web-脚本