题目链接: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. ue4使用SceneCapture2D创建小地图示例 蓝图

    做C++项目的时候遇到了一个小地图的问题,从网上找了个蓝图的思路,转载一下. 原文:https://www.engineworld.cn/thread-3835-1-1.html 本文使用ue4提供的 ...

  2. gradle脚本源码查看环境搭建

    背景 我刚入门学习gradle时,网上资料都是说通过gradle的api查看并学习脚本编写,但是api一般只有接口说明,并不能深入了解各个api的实现逻辑,有时就会对一些脚本的写法感到疑惑.通过搭建源 ...

  3. 【Java例题】4.4使用牛顿迭代法求方程的解

    4. 使用牛顿迭代法求方程的解:x^3-2x-5=0区间为[2,3]这里的"^"表示乘方. package chapter4; public class demo4 { publi ...

  4. 【模板】珂朵莉树(ODT)(Codeforces 896C Willem, Chtholly and Seniorious)

    题意简述 维护一个数列,支持区间加,区间赋值,区间求第k小,区间求幂和 数据随机 题解思路 ODT是一种基于std::set的暴力数据结构. 每个节点对应一段区间,该区间内的数都相等. 核心操作spl ...

  5. 《机器学习技法》---线性SVM

    (本文内容和图片来自林轩田老师<机器学习技法>) 1. 线性SVM的推导 1.1 形象理解为什么要使用间隔最大化 容忍更多的测量误差,更加的robust.间隔越大,噪声容忍度越大: 1.2 ...

  6. Duilib的圆角矩形 抗锯齿优化 弥补RoundRect不足(网易云信borderround版本)

    VListBox class="list" name="list" padding="5,3,5,3" bordersize="1 ...

  7. C#串口类封装 SuperSerialPort

    C#串口类封装 SuperSerialPort 基于SerialPort类做了简单的封装方便调用 代码 /// <summary> /// SuperSerialPort /// < ...

  8. GOF23-单列模式

    1.什么是单例模式 一个类只有一个实列,并且提供一个对外访问该实例的全局访问点. 常见应用场景:数据库连接池,项目中读取配置文件的类,servlet也是单列,Spring中的Bean默认也是单列 2. ...

  9. net core Webapi基础工程搭建(三)——在线接口文档Swagger

    目录 前言 Swagger NuGet引用第三方类库 别急,还有 没错,注释 小结 前言 前后分离的好处,就是后端埋头做业务逻辑功能,不需要过多考虑用户体验,只专注于数据.性能开发,对于前端需要的数据 ...

  10. 小白学Python(6)——python-pptx 添加图表

    添加图表 以下代码在新演示文稿中添加单系列柱形图 from pptx import Presentation from pptx.chart.data import CategoryChartData ...