博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 1890--Robotic Sort(Splay Tree)
阅读量:4608 次
发布时间:2019-06-09

本文共 3208 字,大约阅读时间需要 10 分钟。

题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转。

题解:每次把要的区间转成一棵子树,然后更新。因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后的操作一定不会和前k个数有关,所以每次操作后可以把操作完的数删掉。所以每次把p转到根,然后翻转左子树,删除根就可以了。(也就是p不需要翻转

这个splay处理比较特殊,每个结点的序号就是一开始的位置。splaytree中第i个结点的序号就是第i个数一开始的位置,然后对于每个数排序,记录一开始的位置,就可以在树中直接找到要操作的结点了。

总之。。很神奇。。

#include 
#include
#include
#include
using namespace std;const int INF = 0x5f5f5f5f;const int N = 100005;int root, tot;int sz[N], pre[N], ch[N][2], rev[N];bool which_son(int o) { //判断一个结点是不是父结点的右儿子 return ch[pre[o]][1] == o;}void update_rev(int o) { if (!o) return ; swap(ch[o][0], ch[o][1]); rev[o] ^= 1;}void push_up(int o) { sz[o] = sz[ch[o][0]] + sz[ch[o][1]] + 1;}void push_down(int o) { if (rev[o]) { update_rev(ch[o][0]); update_rev(ch[o][1]); rev[o] = 0; }}void build(int &o, int l, int r, int fa) { if (l > r) return ; int m = (l+r) >> 1; o = m; pre[o]= fa; ch[o][0] = ch[o][1] = 0; sz[o] = 1; rev[o] = 0; build(ch[o][0], l, m-1, o); build(ch[o][1], m+1, r, o); push_up(o);}void init(int n) { root = tot = 0; pre[0] = sz[0] = ch[0][1] = ch[0][0] = rev[0] = 0; build(root, 1, n, 0); push_up(root);}void rotate(int o, int d) { int fa = pre[o]; push_down(fa); push_down(o); ch[fa][!d] = ch[o][d]; pre[ch[o][d]] = fa; pre[o] = pre[fa]; if (pre[fa]) ch[pre[fa]][which_son(fa)] = o; pre[o] = pre[fa]; ch[o][d] = fa; pre[fa] = o; push_up(fa);}void splay(int o, int goal) { push_down(o); while (pre[o] != goal) { if (pre[pre[o]] == goal) { push_down(pre[o]); push_down(o); rotate(o, !which_son(o)); } else { push_down(pre[pre[o]]); push_down(pre[o]); push_down(o); int fa = pre[o]; int d = !which_son(fa); if (ch[fa][d] == o) { rotate(o, !d); rotate(o, d); } else { rotate(fa, d); rotate(o, d); } } } push_up(o); if (goal == 0) root = o;}int get_max(int o) { push_down(o); while (ch[o][1]) { o = ch[o][1]; push_down(o); } return o;}void remove() { if (ch[root][0] == 0) { root = ch[root][1]; pre[root] = 0; } else { int m = get_max(ch[root][0]); splay(m, root); ch[m][1] = ch[root][1]; pre[ch[root][1]] = m; root = m; pre[root] = 0; push_up(root); }}struct node { int v, id; bool operator<(const node rhs) const { if (v == rhs.v) return id < rhs.id; return v < rhs.v; }} a[N];int main(){ //freopen("in.txt", "r", stdin); int n; while (~scanf("%d", &n) && n) { for (int i = 1; i <= n; ++i) { scanf("%d", &a[i].v); a[i].id = i; } sort(a+1, a+1+n); init(n); for (int i = 1; i < n; ++i) { splay(a[i].id, 0); printf("%d ", sz[ch[a[i].id][0]]+i); update_rev(ch[a[i].id][0]); remove(); } printf("%d\n", n); } return 0;}

 

转载于:https://www.cnblogs.com/wenruo/p/5832752.html

你可能感兴趣的文章
PHP 使用POST 获取不到部分数据问题
查看>>
Python第十二课(迭代器/生成器)
查看>>
centos7下搭建Testlink环境详细过程
查看>>
基于 Zen 创建一个 Drupal 7 的主题(模板) ,一份简单的Drupal模板教程
查看>>
Eclipse 中 SVN 提交过滤
查看>>
ACM_招新笔试题系列——买包子
查看>>
IIS无法启动,应用程序池自动关闭
查看>>
面试——认识不一样的自己
查看>>
python Django 学习笔记(一)—— Django安装
查看>>
形参和实参的区别
查看>>
刷题总结:排序机械臂(石室中学oj)(splay)
查看>>
java面向对象的三大特征
查看>>
学 Win32 汇编[28] - 跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等...
查看>>
legend2---开发日志11(如何提高终极开发效率)
查看>>
php面试专题---15、MySQL数据库基础考察点
查看>>
一份好的方案需要注意哪些内容?
查看>>
POJ 3687 Labeling Balls(拓扑排序)题解
查看>>
HDU 3416 Marriage Match IV(ISAP+最短路)题解
查看>>
python_斐波那契数列
查看>>
[HNOI2006]鬼谷子的钱袋
查看>>