HDU 1890 Robotic Sort(splay)
【题目链接】
http://acm.hdu.edu.cn/showproblem.php?pid=1890
【题意】
给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i的所在位置。相等的两个数排序后相对位置不变。
【思路】
由于相对位置不变,所以可以根据数值与位置重编号。
依旧使用直接定位从上到下旋转至根的splay写法。每次将i结点旋转至根,则答案为左儿子大小+i,然后将i删掉合并左右儿子。
需要注意合并时判断左右儿子是否为空,以及各种pushdown下传标记。
【代码】
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 5e5+; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Node *null;
struct Node {
int v,s,rev;
Node *ch[],*fa;
void init(int x) {
v=x;
s=rev=;
ch[]=ch[]=fa=null;
}
void pushdown() {
if(rev) {
swap(ch[],ch[]);
ch[]->rev^=; ch[]->rev^=;
rev=;
}
}
void maintain() {
s=ch[]->s+ch[]->s+;
}
} nodepool[N],*node[N]; void rot(Node* o,int d) {
Node *k=o->ch[d],*tmp=null;
o->ch[d]=k->ch[d^];
if((tmp=k->ch[d^])!=null) tmp->fa=o;
k->ch[d^]=o;
if((tmp=o->fa)!=null) tmp->ch[tmp->ch[]==o]=k;
o->fa=k; k->fa=tmp;
}
Node *st[N<<];
void up_push(Node* u) {
int top=;
while(u!=null)
st[++top]=u,u=u->fa;
while(top)
st[top--]->pushdown();
}
void splay(Node* o,Node* des=null) {
up_push(o);
Node *nf,*nff;
while(o!=des && (nf=o->fa)!=des) {
nff=nf->fa;
if(nff==des) rot(nf,nf->ch[]==o),nf->maintain();
else {
int d1=nf->ch[]==o,d2=nff->ch[]==nf;
if(d1==d2) rot(nff,d2),rot(nf,d1);
else rot(nf,d1),rot(nff,d2);
nff->maintain(),nf->maintain();
}
}
o->maintain();
}
void reverse(Node* o) {
swap(o->ch[],o->ch[]);
o->ch[]->rev^=;
o->ch[]->rev^=;
}
Node* getbound(Node* o,int d) {
o->pushdown();
if(o->ch[]==null&&o->ch[]==null) return o;
if(o->ch[d]!=null) return getbound(o->ch[d],d);
else return o;
}
void merge(Node* u,Node* v) {
if(u->ch[]==null) u->ch[]=v;
else {
u=getbound(u,);
splay(u);
u->ch[]=v;
}
v->fa=u; u->maintain();
} int n,a[N]; Node* build(int l,int r,Node* fa) {
if(l>r) return null;
int mid=l+r>>;
Node* o=node[a[mid]];
o->fa=fa;
o->v=a[mid];
o->ch[]=build(l,mid-,o);
o->ch[]=build(mid+,r,o);
o->maintain();
return o;
}
struct snode {
int a,rank;
bool operator < (const snode& rhs) const {
return a<rhs.a||(a==rhs.a&&rank<rhs.rank);
}
} nodes[N]; int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
while(n=read(),n) {
null=new Node();
FOR(i,,n) {
a[i]=read();
nodes[i]=(snode){a[i],i};
node[i]=&nodepool[i];
nodepool[i].init();
}
sort(nodes+,nodes+n+);
FOR(i,,n) a[nodes[i].rank]=i;
build(,n,null);
FOR(i,,n-) {
Node* o=node[i];
splay(o);
printf("%d ",o->ch[]->s+i);
Node *lc=o->ch[],*rc=o->ch[];
o->ch[]=o->ch[]=null;
lc->fa=rc->fa=null;
if(lc!=null) {
lc->pushdown();
if(rc!=null) rc->pushdown();
reverse(lc);
merge(lc,rc);
}
}
printf("%d\n",n);
}
return ;
}
P.S.好久之前就想切掉这道题了,但一直苦于没有正确的姿势=-=
HDU 1890 Robotic Sort(splay)的更多相关文章
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 1890:Robotic Sort(Splay)
http://acm.hdu.edu.cn/showproblem.php?pid=1890 题意:有一个无序序列,经过不断地翻转,使得最后的序列是一个升序的序列,而且如果相同数字要使在原本序列靠前的 ...
- hdu 1890 Robotic SortI(splay区间旋转操作)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
- HDU 5775 Bubble Sort(冒泡排序)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...
- HDU 1890 Robotic Sort | Splay
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [Pr ...
- 数据结构(Splay平衡树):HDU 1890 Robotic Sort
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 4441 Queue Sequence(splay)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并 ...
- HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Li ...
随机推荐
- Spring + JMS + ActiveMQ实现简单的消息队列(监听器异步实现)
首先声明:以下内容均是在网上找别人的博客综合学习而成的,可能会发现某些代码与其他博主的相同,由于参考的文章比较多,这里对你们表示感谢,就不一一列举,如果有侵权的地方,请通知我,我可以把该文章删除. 1 ...
- JVM最多可创建多少线程
JVM可支持的最大线程数 JVM最大线程数 (2012-07-04 23:20:15) 转载▼ 标签: jvm 最大线程数 it 分类: java分布式总结 摘自:http://sesame.itey ...
- 【问题】和NULL比较遇到的问题
1.问题描述: select FName from teacher where FId not in( select distinct FTeacherId from student ) 子查询返回的 ...
- C#基础(四)
语句 到目前为止,我们的程序还只能按照编写的顺序执行,中途不能发生任何变化 ...
- Uboot 2014.07 makefile分析 - 其他Cortex系列
uboot的官网可以通过谷歌搜索得到,显示结果第一个链接就是. 官网:: http://www.denx.de/wiki/U-Boot ftp下载: ftp://ftp.denx.de/pub/u-b ...
- C#使用sharppcap实现网络抓包-----2
虽然网上已经有了SharpSniffer 这一个SharpSniffer还是原创的无他,唯为学习工程文件下载:SharpSniffer.rar 1.创建套接字2.绑定到本机3.设置IOControl4 ...
- lightOJ 1132 Summing up Powers(矩阵 二分)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1132 题意:给出n和m.求sum(i^m)%2^32.(1<=i<=n) ...
- 深入理解Java虚拟机
1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://nibnait.com/6f8dd084-about-Java-Virtual-Machine/ 2. JVM性能调优 ...
- 1176. Hyperchannels(欧拉回路)
1176 给定一有向图 求其反图的欧拉回路 路径输反了 一直WA.. #include <iostream> #include<cstdio> #include<cstr ...
- bzoj3242
如果是树,那么一定选择树的直径的中点 套了个环?裸的想法显然是断开环,然后求所有树的直径的最小值 环套树dp的一般思路,先把环放到根,把环上点下面的子树dp出来,然后再处理环上的情况 设f[i]表示以 ...