题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890

题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋转方法还有splay tree是按照中序来的,也就是说中序遍历后会得到原序列所以建树和线段树差不多稍微有点不一样。其实splay tree核心操作就是splay就是将某个点移到goal下面优化bst的操作。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 1e5 + ;
int pre[M] , ch[M][] , size[M] , rev[M] , tot , root;//rev类似懒惰标记表示该区间是否要旋转
void NewNode(int &r , int fa , int k) {
r = k;
pre[r] = fa;
ch[r][] = ch[r][] = ;
size[r] = ;
rev[r] = ;
}
void Rev(int r) {
if(!r) return ;
else {
swap(ch[r][] , ch[r][]);
rev[r] ^= ;
}
}//新的操作区间旋转
void push_up(int r) {
size[r] = size[ch[r][]] + size[ch[r][]] + ;
}
void push_down(int r) {
if(rev[r]) {
Rev(ch[r][]);
Rev(ch[r][]);
rev[r] = ;
}
}//新操作的push_down;
void Rotate(int x , int kind) {
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y]) ch[pre[y]][ch[pre[y]][] == y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
push_up(x);
}
void Splay(int r , int goal) {
push_down(r);
while(pre[r] != goal) {
if(pre[pre[r]] == goal) {
push_down(r);
push_down(pre[r]);
Rotate(r , ch[pre[r]][] == r);
}
else {
push_down(r);
push_down(pre[r]);
push_down(pre[pre[r]]);
int y = pre[r];
int kind = (ch[pre[y]][] == y);
if(ch[y][kind] == y) {
Rotate(r , !kind);
Rotate(r , kind);
}
else {
Rotate(y , kind);
Rotate(r , kind);
}
}
}
push_up(r);
if(goal == ) root = r;
}//有新的操作之后注意稍微修改一下旋转操作
int get_Max(int r) {
push_down(r);
while(ch[r][]) {
r = ch[r][];
push_down(r);
}
push_up(r);
return r;
}
void Remove() {
if(!ch[root][]) {
root = ch[root][];
pre[root] = ;
push_up(root);
}
else {
int Max_point = get_Max(ch[root][]);
Splay(Max_point , root);
ch[Max_point][] = ch[root][];
pre[ch[root][]] = Max_point;
root = Max_point;
pre[root] = ;
push_up(root);
}
}//新的remove操作删除节点。
void build(int l , int r , int &x , int fa) {
if(l > r) return ;
int mid = (l + r) >> ;
NewNode(x , fa , mid);
build(l , mid - , ch[x][] , x);
build(mid + , r , ch[x][] , x);
push_up(x);
}
struct TnT {
int pos , val;
}a[M << ];
bool cmp(TnT x , TnT y) {
if(x.val == y.val) return x.pos < y.pos;
return x.val < y.val;
}
int main() {
int n;
while(scanf("%d" , &n) , n) {
for(int i = ; i < n ; i++) {
scanf("%d" , &a[i].val);
a[i].pos = i + ;
}
sort(a , a + n , cmp);
root = tot = ;
pre[root] = ch[root][] = ch[root][] = size[root] = rev[root] = ;
build( , n , root , );
for(int i = ; i < n - ; i++) {
Splay(a[i].pos , );
Rev(ch[root][]);
printf("%d " , size[ch[root][]] + i + );
Remove();
}
printf("%d\n" , n);
}
return ;
}

hdu 1890 Robotic SortI(splay区间旋转操作)的更多相关文章

  1. hdu 1890 Robotic Sort(splay 区间反转+删点)

    题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...

  2. HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Li ...

  3. HDU 1890 Robotic Sort | Splay

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Pr ...

  4. HDU 1890 Robotic Sort (splay tree)

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. splay tree旋转操作 hdu 1890

    很神奇的旋转操作. 目前没看到其他数据结构能实现这个功能.平衡树不好处理区间操作,线段树很难旋转.splay tree搞这个就很简单了. 下面用的这个模板跑了700ms,好慢,估计是删除操作太费时了, ...

  6. HDU 1890 Robotic Sort(splay)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1890 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i ...

  7. 数据结构(Splay平衡树):HDU 1890 Robotic Sort

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. hdu 1890 Robotic Sort

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 如下: #include<cstdio> #include<cstdlib&g ...

  9. hdu1890 Robotic Sort (splay+区间翻转单点更新)

    Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratori ...

随机推荐

  1. 【Android】Failed to convert @drawable/picture into a drawable

    刚使用 eclipse 遇到了这个问题,图片的效果未显示出来,上网查找后发现这其实不算是问题:重启下工程或 eclipse 就行了. PS: 直接运行工程也可以,不影响效果.

  2. 语音控制单片机工作【百度语音识别,串口发送数据到单片机】【pyqt源码+软件】!!

    前些天闲着没事,就做了个语音识别结合串口发送指令的软件,用的是pyqt写的,软件打开后对着笔记本的话筒说话, 他就能识别返回文字结果,然后匹配语音中的关键词,如果有关键词就发送关键词对应的命令,比如语 ...

  3. SpringBoot配置web访问H2

    [**前情提要**]最近开始搭建博客,在本地调试的时候使用的数据库是h2,但是调试的时候需要查看数据库,本文也由此而来. --- 下面是我用到的方法: 1. 使用IDEA的Database连接工具,具 ...

  4. 集成方法 Ensemble

    一.bagging 用于基础模型复杂.容易过拟合的情况,用来减小 variance(比如决策树).基础模型之间没有太多联系(相对于boosting),训练可以并行.但用 bagging 并不能有助于把 ...

  5. final,权限,引用类型数据

    1. final关键字 1.概述 为了避免子类出现随意改写父类的情况,java提供了关键字final,用于修饰不可改变内容 final:不可改变,可以修饰类,方法和变量 类:被修饰的类,不能用于继承 ...

  6. 通过Blazor使用C#开发SPA单页面应用程序(3)

    今天我们来看看Blazor开发的一些基本知识. 一.Blazor组件结构 Blazor中组件的基本结构可以分为3个部分,如下所示: //Counter.razor //Directives secti ...

  7. Rootkit与后门隐藏技术

    目录 简介 linux虚拟文件系统VFS rootkit的功能 隐藏文件 基本方法 高级方法 系统调用流程 hook sys_getdents sys_getdents的调用树 最底层的方法 隐藏进程 ...

  8. 自己实现spring核心功能 一

    聊聊spring spring对于java开发者来说,是最熟悉不过的框架了,我们日常开发中每天都在使用它.它有着各种各样的好处,简单易用,得心应手... ... 我们一说到spring就会讲到ioc ...

  9. 利用递归,反射,注解等,手写Spring Ioc和Di 底层(分分钟喷倒面试官)了解一下

    再我们现在项目中Spring框架是目前各大公司必不可少的技术,而大家都知道去怎么使用Spring ,但是有很多人都不知道SpringIoc底层是如何工作的,而一个开发人员知道他的源码,底层工作原理,对 ...

  10. Swoole引擎原理的快速入门干货

    更多内容,欢迎关注微信公众号:全菜工程师小辉~ 过去一年使用PHP和Java两种技术栈完成了一个游戏服务器项目.由于项目中有高频的网络请求,所以PHP技术栈尝试使用Swoole引擎(基于事件的高性能异 ...