hdu 1890 splay树
Robotic Sort
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3340 Accepted Submission(s): 1423
multimedia lab. But there are still others, serving to their original purposes.
In this task, you are to write software for a robot that handles samples in such a laboratory. Imagine there are material samples lined up on a running belt. The samples have different heights, which may cause troubles to the next processing unit. To eliminate
such troubles, we need to sort the samples by their height into the ascending order.
Reordering is done by a mechanical robot arm, which is able to pick up any number of consecutive samples and turn them round, such that their mutual order is reversed. In other words, one robot operation can reverse the order of samples on positions between
A and B.
A possible way to sort the samples is to find the position of the smallest one (P1) and reverse the order between positions 1 and P1, which causes the smallest sample to become first. Then we find the second one on position P and reverse the order between 2
and P2. Then the third sample is located etc.
The picture shows a simple example of 6 samples. The smallest one is on the 4th position, therefore, the robot arm reverses the first 4 samples. The second smallest sample is the last one, so the next robot operation will reverse the order of five samples on
positions 2–6. The third step will be to reverse the samples 3–4, etc.
Your task is to find the correct sequence of reversal operations that will sort the samples using the above algorithm. If there are more samples with the same height, their mutual order must be preserved: the one that was given first in the initial order must
be placed before the others in the final order too.
of individual samples and their initial order.
The last scenario is followed by a line containing zero.
Each Pi must be an integer (1 ≤ Pi ≤ N ) giving the position of the i-th sample just before the i-th reversal operation.
Note that if a sample is already on its correct position Pi , you should output the number Pi anyway, indicating that the “interval between Pi and Pi ” (a single sample) should be reversed.
3 4 5 1 6 2
4
3 3 2 1
0
4 2 4 4
/*
hdu-1890 splay树g
开始是用伸展树保存的值,然后发现如果有相同的进行了交换,然后输出的值就有问题
3 3 2 1 -> 4 2 4 4 但我的是4 2 4 3,因为我每次是去找的某个值的位置,相同值的话就可能找到较小那个值去了
假设排序后b[3] = b[4]= 3,我先处理b[3],然后b[3],b[4]交换,处理b[4]时就出现了bug,然后GG
准确说是对题意的理解上出现了,果然英语弱O__O "… 后来改用数组坐标建树,对于翻转get_kth找到其中第k个位置,然后get_next找出排序后第i大的后面那个,然后打标记即可.
至于求位置,直接把这个点旋转到根,然后计算左儿子的大小即可 hhh-2016-02-21 01:10:21
*/ #include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
typedef long double ld;
#define key_value ch[ch[root][1]][0]
const int maxn = 300010; int ch[maxn][2];
int pre[maxn],siz[maxn],num[maxn];
int rev[maxn];
int root,tot,cnt,n;
struct Node
{
int val,id;
}node[maxn]; bool cmp(Node a,Node b)
{
if(a.val != b.val) return a.val < b.val;
else return a.id < b.id;
} void push_up(int r)
{
int lson = ch[r][0],rson = ch[r][1];
siz[r] = siz[lson] + siz[rson] + 1;
} void update_rev(int r)
{
if(!r)return ;
swap(ch[r][0],ch[r][1]);
rev[r] ^= 1;
} void push_down(int r)
{
if(rev[r])
{
update_rev(ch[r][0]);
update_rev(ch[r][1]);
rev[r] = 0;
}
} void NewNode(int &r,int far,int k)
{
r = k;
pre[r] = far;
ch[r][0] = ch[r][1] = 0;
siz[r] = 1;
rev[r] = 0;
} void rotat(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);
} void build(int &x,int l,int r,int far)
{
if(l > r) return ;
int mid = (l+r) >>1;
NewNode(x,far,mid);
build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
push_up(x);
} void splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
{
push_down(pre[r]);
push_down(r);
rotat(r,ch[pre[r]][0] == r);
}
else
{
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y]][0] == y;
if(ch[y][kind] == r)
{
rotat(r,!kind);
rotat(r,kind);
}
else
{
rotat(y,kind);
rotat(r,kind);
}
}
}
push_up(r);
if(goal == 0)
root = r;
} int get_kth(int r,int k)
{
push_down(r);
int t = siz[ch[r][0]] + 1;
if(k == t)return r;
if(t > k) return get_kth(ch[r][0],k);
else return get_kth(ch[r][1],k-t);
} int get_next(int r)
{
push_down(r);
if(ch[r][1] == 0)return -1;
r = ch[r][1];
while(ch[r][0])
{
r = ch[r][0];
push_down(r);
}
return r;
} void ini(int n)
{
root = 0;
ch[root][0] = ch[root][1] = pre[root] = siz[root] = num[root] = 0 ;
NewNode(root,0,n+1);
NewNode(ch[root][1],root,n+2);
build(key_value,1,n,ch[root][1]); push_up(ch[root][1]);
push_up(root);
} int main()
{
int q,T;
int cas =1;
while(scanf("%d",&n) != EOF)
{
if(!n)
break;
for(int i=1; i <= n; i++)
{
scanf("%d",&node[i].val);
node[i].id = i;
}
sort(node+1,node+n+1,cmp);
ini(n);
for(int i = 1; i <= n; i++)
{
splay(node[i].id,0);
printf("%d",siz[ch[root][0]]);
if(i != n) printf(" ");
else printf("\n");
splay(get_kth(root,i),0);
splay(get_next(node[i].id),root);
update_rev(key_value);
}
}
return 0;
}
hdu 1890 splay树的更多相关文章
- hdu 3436 splay树+离散化*
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- [置顶] hdu 1890 伸展树区间翻转
题意: 给你n个数,每次先输出第i大的数的位置(如果有多个,选下标小的那个),然后每次将第i个位置到第i大的数所在位置之间的数进行翻转. 思路:输入的数组可能有多个相同的值,我们可以进行两次排序把数组 ...
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
- Splay树学习
首先给出一论文讲的很好: http://www.docin.com/p-63165342.html http://www.docin.com/p-62465596.html 然后给出模板胡浩大神的模板 ...
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- hdu 5314 动态树
Happy King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- Splay树-Codevs 1296 营业额统计
Codevs 1296 营业额统计 题目描述 Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司 ...
随机推荐
- Packet for query is too large (84 > -1).
windows下的resin配置连接mysql,常用的安全的做法是将数据库信息配置到conf目录下的resin.xml文件中. 因为resin连接mysql不是必须的,所以resin本身没有提供mys ...
- 深入浅出 SSL 管理配置实战
我们生活在一个信息大爆炸的时代,几乎每天都在和互联网打交道,购物.网银转账.支付宝付款.搜索信息.查看邮件.观看视频.微信聊天.上网冲浪.阅读新闻等,无不时时刻刻在和网络打交道.那如何保护网络安全就相 ...
- [知识梳理]课本1&2.1-2.5
面向对象的语言 出发点:更直接地描述客观世界中存在的事物(对象)以及它们之间的关系. 特点: 是高级语言. 将客观事物看作具有属性和行为的对象. 通过抽象找出同一类对象的共同属性和行为,形成类. 通过 ...
- Spring+Hibernate+Struts(SSH)框架整合
SSH框架整合 前言:有人说,现在还是流行主流框架,SSM都出来很久了,更不要说SSH.我不以为然.现在许多公司所用的老项目还是ssh,如果改成流行框架,需要成本.比如金融IT这一块,数据库dao层还 ...
- 机器学习中的K-means算法的python实现
<机器学习实战>kMeans算法(K均值聚类算法) 机器学习中有两类的大问题,一个是分类,一个是聚类.分类是根据一些给定的已知类别标号的样本,训练某种学习机器,使它能够对未知类别的样本进行 ...
- LeetCode & Q14-Longest Common Prefix-Easy
String Description: Write a function to find the longest common prefix string amongst an array of st ...
- Python Tornado初学笔记之表单与模板(一)
Tornado中的表单和HTML5中的表单具有相同的用途,同样是用于内容的填写.只是不同的是Tornado中的表单需要传入到后台,然后通过后台进行对模板填充. 模板:是一个允许嵌入Python代码片段 ...
- WebApi 的三种寄宿方式 (一)
最近逛博客园,看到了Owin,学习了一下,做个笔记,说不定将来哪天就用上了 关于 Owin 的介绍,百度解释的很清楚了: https://baike.baidu.com/item/owin/28607 ...
- Spring Security入门(3-4)Spring Security 异常处理、异常传递和异常获取
- Spring MVC的核心流程(步骤)
具体步骤: 1.客户端发送请求先要经过前端控制器,请求被Spring 前端控制器DispatcherServlet获取,如详细图第一步:DispatcherServlet对请求URL进行解析(比如我们 ...