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 ...
随机推荐
- 快速学习bootstrap前台框架
W3c里的解释 使用bootstrap需要注意事项 1. 在html文件第一行要加上<!doctype html>[s1] 2. 导入bootstrap.min.css文件 3. 导 ...
- 测试Tomcat
- ScannerTest-------double string
import java.util.*; public class ScannerTest { public static void main(String[] args){ Scanner scann ...
- go的优缺点
1.1 不允许左花括号另起一行1.2 编译器莫名其妙地给行尾加上分号1.3 极度强调编译速度,不惜放弃本应提供的功能1.4 错误处理机制太原始1.5 垃圾回收器(GC)不完善.有重大缺陷1.6 禁止未 ...
- C++定义全局变量/常量几种方法的区别
在讨论全局变量之前我们先要明白几个基本的概念: 1. 编译单元(模块): 在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LINK ER ...
- 258. Add Digits
题目: Given a non-negative integer num, repeatedly add all its digits until the result has only one di ...
- Android学习之-TextView的滑动效果
textView中如何设置滚动条 在xml中定义: <TextView android:layout_width="wrap_content" ...
- netty websocket协议开发
websocket的好处我们就不用多说了,就是用于解决长连接.服务推送等需要的一种技术. 以下我们来看一个例子: package com.ming.netty.http.websocket; impo ...
- 替代Eval的两种方式
在asp.net中的数据绑定中,我们经常会用到Eval,不过大家都知道Eval绑定是通过反射来实现的, 而反射势必会对性能造成一定的影响.不过有两种替代的方式来实现绑定数据,对性能略有提高. 1 当数 ...
- eclipse教程
http://www.eclipse.org/downloads/eclipse-packages/http://wiki.eclipse.org/Eclipse_Articles,_Tutorial ...