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

转载于:https://www.cnblogs.com/TnT2333333/p/7204188.html

hdu 1890 Robotic SortI(splay区间旋转操作)相关推荐

  1. HDU - 1890 Robotic Sort(Splay-区间翻转+删除根节点)

    题目链接:点击查看 题目大意:给出一个序列,初始时是乱序的,要求根据规则排序,规则是,遍历每一个点 i ,使得区间 [ i , a[ i ] ] 内的数翻转,a[ i ] 表示的是数列中第 i 大的数 ...

  2. splay的一些操作

    秦同学的详细版本 splay就是一种将树上的一个节点经过旋转到节点的一种操作,来保持树的平衡 splay本质:二叉搜索树 特点:结点x的左子树权值都小于x的权值,右子树权值都大于x的权值 如果当前处于 ...

  3. [置顶] hdu 1890 伸展树区间翻转

    题意: 给你n个数,每次先输出第i大的数的位置(如果有多个,选下标小的那个),然后每次将第i个位置到第i大的数所在位置之间的数进行翻转. 思路:输入的数组可能有多个相同的值,我们可以进行两次排序把数组 ...

  4. Splay_Tree 模板(区间修改,旋转操作)

    1.旋转操作 #define MAXN 100100bool Add[MAXN];//延迟标记struct Splay_Tree {int cnt, rt;//cnt为节点数,rt == rootst ...

  5. 数据结构——算法之(010)( 字符串的左旋转操作)

    [申明:本文仅限于自我归纳总结和相互交流,有纰漏还望各位指出. 联系邮箱:Mr_chenping@163.com] 题目:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部.如把字符串 ...

  6. C#实现字符串左旋转操作

    竞赛题目及要求: 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部.如把字符串abcdef左旋转2位得到字符串cdefab. 要求:对长度为n的字符串操作的时间复杂度为O(n),空间 ...

  7. 数据结构-----AVL树的旋转操作

    本文主要讲解AVL的旋转操作,供自己复习用,如有不对之处请指出.另外图片是从链接处的大神那复制的,感觉文章写的很好,可以去学习. http://www.cnblogs.com/QG-whz/p/516 ...

  8. 红黑树 键值_Java集合框架:红黑树概念、插入及旋转操作详细解读就问你会不会...

    初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储角度考虑,这两种数据结构是非常优秀的.另外, ...

  9. Android单点触控技术,对图片进行平移,缩放,旋转操作

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/42833893),请尊重他人的辛勤劳动成果,谢谢! 相信大家 ...

  10. MATLAB对三阶魔方建模并进行旋转操作

    对于魔方的表示: 先看一串天书般的字母:UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR 这种表示法是由一个叫Mi ...

最新文章

  1. 反转链表JAVA算法_链表反转算法
  2. 域控服务器发生w32time错误
  3. css中单位em和rem
  4. 虚拟内存越大越好吗_滤波电容越大越好吗?
  5. LeetCode 1004.最长连续1的个数
  6. 小熊维尼项目冲刺 第三天
  7. 举例介绍活动目录的优势
  8. 反思 大班 快乐的机器人_幼儿园大班音乐优秀教案《小青蛙找家》含反思
  9. 使用 Selenium开展Web测试
  10. win10鼠标右键拓展(使用vs Code打开)
  11. 在linux下MySQL的常用操作命令
  12. Findbugs使用指南及扫描内容解释
  13. Centos7安装Docker,阿里源,网易镜像
  14. 【Shotcut】沧海桑田_转场效果
  15. 线下门店如何进行私域运营
  16. Scrum立会报告+燃尽图(Beta阶段第三次)
  17. mysql数据库安装最详解
  18. 直击汇佳学校|中考后转轨国际学校 重大改变的他们现在如何?
  19. 为了让师妹20分钟学会canvas,我熬夜苦肝本文外加一个小项目【❤️建议收藏❤️】
  20. 学会用打码平台处理验证码

热门文章

  1. Could not load file or assembly 'MagickNet.dll'
  2. SQL查询-将列转换成字符串(for xml path)
  3. Python中导包问题
  4. BERT加速 | 预训练模型参数量越来越大?这里有你需要的BERT推理加速技术指南...
  5. SpanBERT: 抽取式问答的利器
  6. 你一直在用的Beam Search,是否真的有效?
  7. NLP的12种后BERT预训练方法
  8. AttributeError: ‘_thread._local‘ object has no attribute ‘value‘
  9. ICLR最佳论文“彩票假设”:如何通过彩票假设构建轻量化模型(上)
  10. 李宏毅自然语言处理——文本风格转换