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,这种情况下,每次 ...
随机推荐
- c++内存中字节对齐问题详解
一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址 ...
- 深入理解JVM--JVM垃圾回收机制
Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放空间,既要写构造函数,又要写析构函数,很多时候都 ...
- Agri Net POJ1258 && Constructing Roads POJ2421
题意,在给出的图中,使用最小花费的边,使这个图仍然连通. #include <cstdio> #include <algorithm> #include <cstring ...
- Random Integer Generator
先占坑.以后再修改 昨天遇到一道题, Given int Rand(1) = 0或者 1- uniformly distributed, write a function to implemen ...
- windows下配置环境变量时,在cmd窗口执行配置的命令时无效的原因
一个原因肯定就是配置错误,这个就要自己仔细去检查了,如果确信配置正确,可能是你的cmd窗口在环境变量配置之前就打开的,在配置好环境变量之后,在cmd窗口执行命令是看不到效果的,可以关掉cmd窗口再重新 ...
- 再谈 retain,copy,mutableCopy(官方SDK,声明NSString都用copy非retain)
之前一直以为retain就是简单的计数器+1,copy就是重新开辟内存复制对象: 其实不是这样,原来之前的自己独自徘徊于糊涂之中. (官方SDK,对NSString属性的定义都是用copy,而不是re ...
- python学习笔记一--字符串
一.字符串: (一)字符串里单个元素的操作 1. 单个字符(元素)的序列组合. 2. 序列:单个字符的位置 3. 序列的操作:内置函数len获取长度,加位置索引 4. 获取字符串的里的元素:正向索引+ ...
- CentOS7.1 Xshell 经常掉线 Connection closed by foreign host
XShell如果经常对CentOS掉线,则VNC肯定连接不上 但是ping CentOS的IP又能ping通,主要原因还是因为sshd的设置问题 #进入ssh目录 cd /etc/ssh #修改ssh ...
- linux系统中删除文件夹
rm -rf 文件夹的名称 rm-r 文件名称
- awesome cpp
https://github.com/fffaraz/awesome-cpp Awesome C/C++ A curated list of awesome C/C++ frameworks, lib ...