题目链接: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. python中对多态的理解

    目录 python中对多态的理解 一.多态 二.多态性 三.鸭子类型 python中对多态的理解 一.多态 多态是指一类事物有多种形态,比如动物类,可以有猫,狗,猪等等.(一个抽象类有多个子类,因而多 ...

  2. 虚拟机ip地址从ipv6改为ipv4相关问题

    有一次打开虚拟机时,Xshell连接不上虚拟机,就很奇怪,然后查看虚拟机的ip地址,发现显示为ipv6格式,然后总结了两种情况如下: 第一种情况: onboot为no时显示ipv6地址, 改为yes即 ...

  3. 用JavaScript带你体验V8引擎解析标识符过程

    上一篇讲了字符串的解析过程,这一篇来讲讲标识符(IDENTIFIER)的解析. 先上知识点,标识符的扫描分为快解析和慢解析,一旦出现Ascii值大于128的字符或者转义字符,会进入慢解析,略微影响性能 ...

  4. 浏览器输入URL到返回页面的全过程

    [问题描述] 在浏览器输入www.baidu.com,然后,浏览器显示相应的百度页面,这个过程究竟发生了什么呢? [第一步,解析域名,找到主机] 正常情况下,浏览器会缓存DNS一段时间,一般2分钟到3 ...

  5. 防止sql注入:替换危险字符

    在用户名或者密码框中输入“11‘ or ’1‘ = '1”时,生成的sql语句将为“selec * from userInfo where name = '11' or '1' = '1' and p ...

  6. Oauth2认证模式之授权码模式实现

    Oauth2认证模式之授权码模式(authorization code) 本示例实现了Oauth2之授权码模式,授权码模式(authorization code)是功能最完整.流程最严密的授权模式.它 ...

  7. 用python实现银行家算法

    编制模拟银行家算法的程序,并以下面给出的例子验证所编写的程序的正确性. 进程 已占资源 最大需求数 资源种类 A B C D A B C D P0 0 0 1 2 0 0 1 2 P1 1 0 0 0 ...

  8. 洛谷 P1196 [NOI2002]银河英雄传说

    题意简述 有30000列,每列都有一艘战舰,编号1~30000 有2种操作: 1.将一列的战舰运到另一列 2.询问两个战舰是否在同一列,如果是,求出它们之间的距离 题解思路 并查集, 维护每个点x离自 ...

  9. 管理Windows Server 2008本地用户和组

    下面介绍Windows Server 2008本地用户和组的管理包括创建用户.删除用户.重设密码.将用户添加到组.普通用户跟管理员的区别 .用户配置文件包括桌面上文件,桌面背景,桌面上图标,IE设置, ...

  10. 中间件增强框架之InterceptFramework

    本文讲解MOF中的InterceptFramework框架.该框架可以在应用启动过程中获取画像信息,实现应用画像数据采集和存储. 一.前言 在智能运维中,应用服务所使用的组件及JAR包等相关信息非常重 ...