题目链接: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. Chrome 使用 Evernote 插件

    Chrome 插件不能登印象笔记进行裁剪,被困扰有段时间了.昨天偶然在知乎上找到了解决方法: 链接:https://www.zhihu.com/question/20340803/answer/291 ...

  2. redis过期策略与内存淘汰机制分析

    过期策略: 我们在set key时,可以给一个expire time,就是过期时间 这段过期时间以后,redis对key删除使用:定期删除+惰性删除 定期删除指redis默认在100ms内随机抽取一些 ...

  3. SpringBoot开发案例之打造十万博文Web篇

    前言 通过 Python 爬取十万博文之后,最重要的是要让互联网用户访问到,那么如何做呢? 选型 从后台框架.前端模板.数据库连接池.缓存.代理服务.限流等组件多个维度选型. 后台框架 SpringB ...

  4. Discuz论坛 自动加好友留言程序

    目录 [隐藏] 1 思路: 2 代码: 2.1 登录,获取Cookie: 2.2 获取FormHash: 2.3 发送加好友请求并留言: 思路: 一波未平一波又起, 拿到这个需求的时候对我来说还是有挑 ...

  5. npm 一些有用的提示和技巧

    生成 package.json 我们通常执行 npm init,然后开始添加 npm 请求的信息. 但是,如果我们不关心所有这些信息,并且希望保留默认值,那么对于 npm 请求的每一条数据,我们都按 ...

  6. 【Java例题】2.3 计算银行存款本息

    3.计算银行存款本息. 用户输入存款金额money,存款期years和年利率rate, 根据公式: sum=money(1+rate)^years ,计算到期存款本息. 这里的"^" ...

  7. 逆向破解之160个CrackMe —— 004-005

    CrackMe —— 004 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  8. Netty学习(一)-为什么选择Netty

    前面我们简单学习了NIO.我们知道java的I/O模型一共有四种,分别是:传统的BIO,伪异步I/O,NIO和AIO.为了澄清概念和分清区别,我们还是先简单的介绍一下他们的概念,然后再去比较优劣.以及 ...

  9. 主成分分析 Principle Component Analysis

    一.主要思想 利用正交变换把可能线性相关变量表示的观测数据,转换为由少数几个线性无关变量(主成分)表示的数据.(重构原始特征空间:线性降维) 要尽可能保留原始数据中的信息,两个思路:最大投影方差.最小 ...

  10. flask项目部署到云服务器+域名绑定

    一.效果演示 首页展示 播放页面 该项目部署只为学习,所以用的服务器是腾讯云服务器10元/月,域名也是在腾讯云买的.com 55元/年  因为本人比较穷 哈哈