hdu-1890-Robotic Sort splay区间翻转
题意:
依次找第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区间翻转的更多相关文章
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
- HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 Time Limit: 6000/2000 MS (Java/Others) Memory Li ...
- HDU 1890 Robotic Sort | Splay
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [Pr ...
- hdu1890 Robotic Sort (splay+区间翻转单点更新)
Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratori ...
- 数据结构(Splay平衡树):HDU 1890 Robotic Sort
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 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 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i ...
- hdu 1890 Robotic Sort
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 如下: #include<cstdio> #include<cstdlib&g ...
- hdu 1890 Robotic SortI(splay区间旋转操作)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...
随机推荐
- switch-case参数类型
switch语句用法: 0. switch语句由一个控制表达式和多个case标签组成 1. switch控制表达式支持的类型有byte.short.char.int.enum(JDK5).String ...
- [iOS开发] 使用第三方字体不生效
iOS中使用第三方字体并不复杂,通常只需要如下三个步骤: 1. 将第三方字体文件添加到工程(Project)中: 2. 在info.plist中添加一个新的键"Fonts provided ...
- Ant学习笔记(1) 基础知识
Ant Apache Ant 是一个基于 Java的构建工具. 下载Ant google.baidu.Windows用户下载zip格式.解压即可. Windows安装Ant Ant本质上是一个Java ...
- (转)兼容主流浏览器的CSS透明代码
透明往往能产生不错的网页视觉效果下面是兼容主流浏览器的CSS透明代码.transparent_class { filter:alpha(opacity=50); -moz-opacity:0.5; - ...
- 关于git status
如果只在本地修改,还没有commit,那么用git status, 打印信息为: 如果我本地没有修改文件,就是:
- 【转】Windows环境下.NET 操作Oracle问题
目前,Windows操作系统可以分成两类,32位和64位(64位也区分x86_64位和Itanium ),同时Oracle客户端也做了同样的区分. 在安装和开发的过程中,经常会遇到一些问题,本文就总结 ...
- 在eclipse中将java导出为可执行文件.
Ref: http://java.chinaitlab.com/Eclipse/812775.html and http://www.javavids.com/video/how-to-create- ...
- 解决kernel headers报错
Make sure you have updated version $ sudo apt-get update Search for kernel version (optional) $ apt- ...
- 强大的Core Image框架,各种滤镜处理图像
首先介绍一下Core Image,他是一个很强大的图像处理框架,他可以让你简单的应用各种滤镜来处理图像,比如说色相,饱和度,亮度等等...他是运用GPU(CPU)实时地处理图像数据和视频的帧.而且Co ...
- ios手势复习值之换图片-转场动画(纯代码)
目标:实现通过手势进行图片的切换 通过左扫右扫 来实现(纯代码) 添加三个属性 1uiImageView 用来显示图片的view 2 index 用来表示图片的索引 3 ISLeft 判断是不是向 ...