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 ...
随机推荐
- Linux中断处理体系结构分析
Linux中断处理体系结构分析(一) 异常,就是可以打断CPU正常运行流程的一些事情,比如外部中断.未定义指令.试图修改只读的数据.执行swi指令(Software Interrupt Instruc ...
- TCL语言笔记:TCL练习二
一.练习 1.二进制转十进制 proc b2d {b} { ;set len [string length $b] } {$i<$len} {incr i} { incr sum [expr , ...
- JavaWeb项目开发案例精粹-第2章投票系统-001设计
1.项目结构 2.数据库设计 # MySQL-Front 5.0 (Build 1.0) /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE */; /*!40101 SET ...
- go的优缺点
1.1 不允许左花括号另起一行1.2 编译器莫名其妙地给行尾加上分号1.3 极度强调编译速度,不惜放弃本应提供的功能1.4 错误处理机制太原始1.5 垃圾回收器(GC)不完善.有重大缺陷1.6 禁止未 ...
- 每用户订阅上的所有者 SID 不存在 (异常来自 HRESULT:0x80040207)
出现这个问题是因为pQueryFilter.WhereClause = "RoomNumber=" +cmbFromPoint.SelectedItem;中的cmbFromPoin ...
- yii2 学习中
属性: public function __get($name) // 这里$name是属性名 { $getter = 'get' . $name; // getter函数的函数名 if (metho ...
- YASKAWA电机控制(1)---接线
实验室所购置电机型号为YASKAWA-AC SERVO MOTOR SGM7J-01AFC6S型,配SGD7S-R90A00A002伺服控制器.电机和控制器的操作说明书由安川中文官网安川电机资料提供. ...
- python处理Excel
Python中一般使用xlrd库来读取Excel文件,使用xlwt库来生成Excel文件,使用xlutils库复制和修改Excel文件.这三个库只支持到Excel2003. python-excel主 ...
- JVM学习笔记(二)------Java代码编译和执行的整个过程
Java代码编译是由Java源码编译器来完成,流程图如下所示: Java字节码的执行是由JVM执行引擎来完成,流程图如下所示: Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码 ...
- NDK 提示"undefined reference to xxx“的解决办法
在Android.mk文件的 LOCAL_SRC_FILES后面加入包含该类或函数的文件,用\隔开,\后换行继续添加 例如 LOCAL_SRC_FILES := NDKTest.cpp\bncore. ...