题意:

依次找第i大的数下标pos[i],然后将区间[i,pos[i]]翻转

分析:

splay树区间翻转

// File Name: ACM/HDU/1890.cpp
// Author: Zlbing
// Created Time: 2013年08月10日 星期六 20时26分39秒 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
#define L ch[x][0]
#define R ch[x][1]
#define KT (ch[ ch[rt][1] ][0])
const int MAXN = ;
int cmp(pair<int,int> a,pair<int,int> b){
if(a.first!=b.first) return a.first<b.first;
return a.second < b.second;
}
int mp[MAXN];
int id[MAXN];
pair<int,int> num[MAXN];
struct SplayTree {
int sz[MAXN];
int ch[MAXN][];
int pre[MAXN];
int rt,top;
inline void down(int x){
if(flip[x]) {
flip[ L ] ^= ;
flip[ R ] ^= ;
swap(L,R);
flip[x]=;
}
}
inline void up(int x){
sz[x]=+sz[ L ] + sz[ R ];
}
inline void Rotate(int x,int f){
int y=pre[x];
down(y);
down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][] == y ] =x;
ch[x][f] = y;
pre[y] = x;
up(y);
}
inline void Splay(int x,int goal){//将x旋转到goal的下面
down(x);//防止pre[x]就是目标点,下面的循环就进不去了,x的信息就传不下去了
while(pre[x] != goal){
down(pre[pre[x]]); down(pre[x]);down(x);//在旋转之前需要先下传标记,因为节点的位置可能会发生改变
if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][] == x);
else {
int y=pre[x],z=pre[y];
int f = (ch[z][]==y);
if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
else Rotate(y,f),Rotate(x,f);
}
}
up(x);
if(goal==) rt=x;
}
inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
int x=rt;
down(x);
while(sz[ L ]+ != k) {
if(k < sz[ L ] + ) x=L;
else {
k-=(sz[ L ]+);
x = R;
}
down(x);
}
Splay(x,goal);
}
void vist(int x){
if(x){
printf("结点%2d : 左儿子 %2d 右儿子 %2d %2d flip:%d\n",x,L,R,val[x],flip[x]);
vist(L);
vist(R);
}
}
void Newnode(int &x,int c,int f){
x=++top;flip[x]=;
L = R = ; pre[x] = f;
sz[x]=; val[x]=c;
}
inline void build(int &x,int l,int r,int f){
if(l>r) return ;
int m=(l+r)>>;
Newnode(x,num[id[m]].first,f);
mp[id[m]]=x;
build(L , l , m- , x);
build(R , m+ , r , x);
pre[x]=f;
up(x);
} inline void init(){
ch[][]=ch[][]=pre[]=sz[]=;
rt=top=; flip[]=; val[]=;
}
void Del(){
int t=rt;
if(ch[rt][]) {
rt=ch[rt][];
RTO(,);
ch[rt][]=ch[t][];
if(ch[rt][]) pre[ch[rt][]]=rt;
}
else rt=ch[rt][];
pre[rt]=;
up(rt);
}
int flip[MAXN];
int val[MAXN];
}spt;
int main()
{
int n;
while(~scanf("%d",&n))
{
if(!n)break;
spt.init();
REP(i,,n)
{
scanf("%d",&num[i].first);
num[i].second=i;
}
sort(num+,num+n+,cmp);
REP(i,,n)
id[num[i].second]=i;
spt.build(spt.rt,,n,); REP(i,,n)
{
spt.Splay(mp[i],);
int ans=i+spt.sz[spt.ch[spt.rt][]];
spt.flip[spt.ch[spt.rt][]]^=;
spt.Del();
if(i==)printf("%d",ans);
else printf(" %d",ans);
}
printf("\n");
}
return ;
}

hdu-1890-Robotic Sort splay区间翻转的更多相关文章

  1. hdu 1890 Robotic Sort(splay 区间反转+删点)

    题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...

  2. HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Li ...

  3. HDU 1890 Robotic Sort | Splay

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Pr ...

  4. hdu1890 Robotic Sort (splay+区间翻转单点更新)

    Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratori ...

  5. 数据结构(Splay平衡树):HDU 1890 Robotic Sort

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. HDU 1890 Robotic Sort (splay tree)

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. HDU 1890 Robotic Sort(splay)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1890 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i ...

  8. hdu 1890 Robotic Sort

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 如下: #include<cstdio> #include<cstdlib&g ...

  9. hdu 1890 Robotic SortI(splay区间旋转操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...

随机推荐

  1. switch-case参数类型

    switch语句用法: 0. switch语句由一个控制表达式和多个case标签组成 1. switch控制表达式支持的类型有byte.short.char.int.enum(JDK5).String ...

  2. [iOS开发] 使用第三方字体不生效

    iOS中使用第三方字体并不复杂,通常只需要如下三个步骤: 1. 将第三方字体文件添加到工程(Project)中: 2. 在info.plist中添加一个新的键"Fonts provided ...

  3. Ant学习笔记(1) 基础知识

    Ant Apache Ant 是一个基于 Java的构建工具. 下载Ant google.baidu.Windows用户下载zip格式.解压即可. Windows安装Ant Ant本质上是一个Java ...

  4. (转)兼容主流浏览器的CSS透明代码

    透明往往能产生不错的网页视觉效果下面是兼容主流浏览器的CSS透明代码.transparent_class { filter:alpha(opacity=50); -moz-opacity:0.5; - ...

  5. 关于git status

    如果只在本地修改,还没有commit,那么用git status, 打印信息为: 如果我本地没有修改文件,就是:

  6. 【转】Windows环境下.NET 操作Oracle问题

    目前,Windows操作系统可以分成两类,32位和64位(64位也区分x86_64位和Itanium ),同时Oracle客户端也做了同样的区分. 在安装和开发的过程中,经常会遇到一些问题,本文就总结 ...

  7. 在eclipse中将java导出为可执行文件.

    Ref: http://java.chinaitlab.com/Eclipse/812775.html and http://www.javavids.com/video/how-to-create- ...

  8. 解决kernel headers报错

    Make sure you have updated version $ sudo apt-get update Search for kernel version (optional) $ apt- ...

  9. 强大的Core Image框架,各种滤镜处理图像

    首先介绍一下Core Image,他是一个很强大的图像处理框架,他可以让你简单的应用各种滤镜来处理图像,比如说色相,饱和度,亮度等等...他是运用GPU(CPU)实时地处理图像数据和视频的帧.而且Co ...

  10. ios手势复习值之换图片-转场动画(纯代码)

    目标:实现通过手势进行图片的切换   通过左扫右扫 来实现(纯代码) 添加三个属性 1uiImageView 用来显示图片的view 2 index 用来表示图片的索引 3 ISLeft 判断是不是向 ...