HDU 1890--Robotic Sort(Splay Tree)
题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转。
题解:每次把要的区间转成一棵子树,然后更新。因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后的操作一定不会和前k个数有关,所以每次操作后可以把操作完的数删掉。所以每次把p转到根,然后翻转左子树,删除根就可以了。(也就是p不需要翻转
这个splay处理比较特殊,每个结点的序号就是一开始的位置。splaytree中第i个结点的序号就是第i个数一开始的位置,然后对于每个数排序,记录一开始的位置,就可以在树中直接找到要操作的结点了。
总之。。很神奇。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0x5f5f5f5f;
const int N = ; int root, tot;
int sz[N], pre[N], ch[N][], rev[N]; bool which_son(int o) { //判断一个结点是不是父结点的右儿子
return ch[pre[o]][] == o;
} void update_rev(int o) {
if (!o) return ;
swap(ch[o][], ch[o][]);
rev[o] ^= ;
} void push_up(int o) {
sz[o] = sz[ch[o][]] + sz[ch[o][]] + ;
} void push_down(int o) {
if (rev[o]) {
update_rev(ch[o][]);
update_rev(ch[o][]);
rev[o] = ;
}
} void build(int &o, int l, int r, int fa) {
if (l > r) return ;
int m = (l+r) >> ;
o = m;
pre[o]= fa;
ch[o][] = ch[o][] = ;
sz[o] = ;
rev[o] = ;
build(ch[o][], l, m-, o);
build(ch[o][], m+, r, o);
push_up(o);
} void init(int n) {
root = tot = ;
pre[] = sz[] = ch[][] = ch[][] = rev[] = ;
build(root, , n, );
push_up(root);
} void rotate(int o, int d) {
int fa = pre[o];
push_down(fa);
push_down(o);
ch[fa][!d] = ch[o][d];
pre[ch[o][d]] = fa;
pre[o] = pre[fa];
if (pre[fa]) ch[pre[fa]][which_son(fa)] = o;
pre[o] = pre[fa];
ch[o][d] = fa;
pre[fa] = o;
push_up(fa);
} void splay(int o, int goal) {
push_down(o);
while (pre[o] != goal) {
if (pre[pre[o]] == goal) {
push_down(pre[o]);
push_down(o);
rotate(o, !which_son(o));
} else {
push_down(pre[pre[o]]);
push_down(pre[o]);
push_down(o);
int fa = pre[o];
int d = !which_son(fa);
if (ch[fa][d] == o) {
rotate(o, !d);
rotate(o, d);
} else {
rotate(fa, d);
rotate(o, d);
}
}
}
push_up(o);
if (goal == ) root = o;
} int get_max(int o) {
push_down(o);
while (ch[o][]) {
o = ch[o][];
push_down(o);
}
return o;
} void remove() {
if (ch[root][] == ) {
root = ch[root][];
pre[root] = ;
} else {
int m = get_max(ch[root][]);
splay(m, root);
ch[m][] = ch[root][];
pre[ch[root][]] = m;
root = m;
pre[root] = ;
push_up(root);
}
} struct node {
int v, id;
bool operator<(const node rhs) const {
if (v == rhs.v) return id < rhs.id;
return v < rhs.v;
}
} a[N]; int main()
{
//freopen("in.txt", "r", stdin);
int n;
while (~scanf("%d", &n) && n) {
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i].v);
a[i].id = i;
}
sort(a+, a++n);
init(n);
for (int i = ; i < n; ++i) {
splay(a[i].id, );
printf("%d ", sz[ch[a[i].id][]]+i);
update_rev(ch[a[i].id][]);
remove();
}
printf("%d\n", n);
} return ;
}
HDU 1890--Robotic Sort(Splay Tree)的更多相关文章
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 1890 Robotic Sort(splay)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1890 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i ...
- hdu 1890 Robotic SortI(splay区间旋转操作)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
- 伸展树(Splay Tree)进阶 - 从原理到实现
目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...
- 数据结构(二) --- 伸展树(Splay Tree)
文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...
- HDU 1890 Robotic Sort | Splay
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [Pr ...
- 数据结构(Splay平衡树):HDU 1890 Robotic Sort
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 纸上谈兵:伸展树(splay tree)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...
随机推荐
- Injection Attacks-Log 注入
日志注入(也称日志文件注入) 很多应用都维护着一系列面向授权用户.通过 HTML 界面展示的日志,因而成为了攻击者的首要目标,这些攻击者试图伪装其他攻击.误导日志读者,甚至对阅读和分析日志监测应用的用 ...
- hdu 4794 FIb求循环节
很容易看出来这道题是求模n意义下fib数列的最小循环节 对于fib数列的最小循环节的求法,我们可以这样: 1.令n=p1^m1 * p2^m2 * p3^m3…… 2.分别计算fib数列在模p1^m1 ...
- Fast Matrix Operations
A Simple Problem with Integers 每次将区间向下更新,或是用之前的方法,统计当前节点到父节点处的覆盖数目. #include <cstdio> #include ...
- POJ2524——Ubiquitous Religions
Ubiquitous Religions Description There are so many different religions in the world today that it is ...
- Spring RestTemplate介绍
http://www.cnblogs.com/rollenholt/p/3894117.html RestTemplate 这篇文章打算介绍一下Spring的RestTemplate.我这边以前设计到 ...
- 如何保存ISE综合后的RTL schematic为pdf
如何保存ISE综合后的RTL schematic为pdf 2013-06-23 20:50:10 代码进行综合后,可以得到一个ngr文件,在ISE中打开该文件可以打开RTL schematic,这样每 ...
- 在XML里的XSD和DTD以及standalone的使用
有关XML结构中的XSD和DTD以及standalone的使用 XmlDeclaration declare= document.CreateXmlDeclaration("1.0" ...
- ORACLE-修改当前会话的语言环境
修改当前会话的语言环境变量参数:ALTER SESSION SET =将语言改为英语: SQL> ALTER SESSION SET NLS_LANGUAGE='AMERICAN';SESSIO ...
- HTML5学习(五)----SVG
参考教程地址:http://www.w3school.com.cn/html5/html_5_svg.asp HTML5 支持内联 SVG. 什么是SVG? SVG 指可伸缩矢量图形 (Scalabl ...
- J2EE中你必须了解的13种技术规范
1)JDBC(Java Database Connectivity): JDBC API为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对开发者屏蔽了一些细节问题,另外,JDCB对数据 ...