题目描述

输入

输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

输出

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

样例输入

6
3 4 5 1 6 2

样例输出

4 6 4 5 6 6


题解

splay

先将原数据从小到大排序,类似于离散化,把它们的排名存入splay中。

那么第k小的数的数组下标就是k。

区间反转即可。

#include <cstdio>
#include <algorithm>
#define N 100005
using namespace std;
struct data
{
int num , pos;
}a[N];
int c[2][N] , fa[N] , tag[N] , si[N] , id[N] , root;
bool cmp(data a , data b)
{
return a.num == b.num ? a.pos < b.pos : a.num < b.num;
}
void pushup(int k)
{
si[k] = si[c[0][k]] + si[c[1][k]] + 1;
}
void pushdown(int k)
{
if(tag[k])
{
swap(c[0][c[0][k]] , c[1][c[0][k]]);
swap(c[0][c[1][k]] , c[1][c[1][k]]);
tag[c[0][k]] ^= 1;
tag[c[1][k]] ^= 1;
tag[k] = 0;
}
}
void build(int l , int r , int f)
{
if(l > r) return;
int mid = (l + r) >> 1;
build(l , mid - 1 , mid);
build(mid + 1 , r , mid);
fa[id[mid]] = id[f];
c[mid > f][id[f]] = id[mid];
pushup(id[mid]);
}
void rotate(int &k , int x)
{
int y = fa[x] , z = fa[y] , l , r;
l = (c[0][y] != x);
r = l ^ 1;
if(y == k) k = x;
else if(c[0][z] == y) c[0][z] = x;
else c[1][z] = x;
fa[x] = z;
fa[y] = x;
fa[c[r][x]] = y;
c[l][y] = c[r][x];
c[r][x] = y;
pushup(y);
pushup(x);
}
void splay(int &k , int x)
{
while(x != k)
{
int y = fa[x] , z = fa[y];
if(y != k)
{
if(c[0][y] == x ^ c[0][z] == y) rotate(k , x);
else rotate(k , y);
}
rotate(k , x);
}
}
int getrank(int x)
{
if(x == root) return si[c[0][x]] + 1;
int r = getrank(fa[x]);
pushdown(x);
if(x == c[0][fa[x]]) r -= si[c[1][x]] + 1;
else r += si[c[0][x]] + 1;
return r;
}
int find(int k , int x)
{
pushdown(k);
if(x <= si[c[0][k]]) return find(c[0][k] , x);
else if(x > si[c[0][k]] + 1) return find(c[1][k] , x - si[c[0][k]] - 1);
else return k;
}
int main()
{
int n , i;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d" , &a[i].num);
a[i].pos = i;
}
sort(a + 1 , a + n + 1 , cmp);
for(i = 1 ; i <= n ; i ++ )
id[a[i].pos + 1] = i;
id[1] = n + 1;
id[n + 2] = n + 2;
build(1 , n + 2 , 0);
root = id[(n + 3) >> 1];
for(i = 1 ; i <= n ; i ++ )
{
int ri = getrank(i) , tx , ty;
printf("%d%c" , ri - 1 , i == n ? '\n' : ' ');
tx = find(root , i);
ty = find(root , ri + 1);
splay(root , tx);
splay(c[1][root] , ty);
swap(c[0][c[0][c[1][root]]] , c[1][c[0][c[1][root]]]);
tag[c[0][c[1][root]]] ^= 1;
}
return 0;
}

【bzoj1552】[Cerc2007]robotic sort的更多相关文章

  1. 【BZOJ1552】[Cerc2007]robotic sort Splay

    [BZOJ1552][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N ...

  2. 【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值

    [bzoj1552/3506][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. ...

  3. 洛谷 P4402 BZOJ1552 / 3506 [Cerc2007]robotic sort 机械排序

    FHQ_Treap 太神辣 蒟蒻初学FHQ_Treap,于是来到了这道略显板子的题目 因为Treap既满足BST的性质,又满足Heap的性质,所以,对于这道题目,我们可以将以往随机出的额外权值转化为每 ...

  4. 【HDOJ】1890 Robotic Sort

    伸展树伤不起啊,很容易wa,很容易T,很容易M. /* 1890 */ #include <iostream> #include <string> #include <m ...

  5. BZOJ1552/3506 [Cerc2007]robotic sort

    Splay 与之前不同的是如果你仅仅是翻转左右区间的话可以在find里面做因为对他有影响的子树在做之前一定在他的上面从上到下搜索的过程可以把rever做了. 但这道题要求我们输出转换之前的,因此不能保 ...

  6. [BZOJ1552][Cerc2007]robotic sort

    [BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...

  7. BZOJ 1552: [Cerc2007]robotic sort( splay )

    kpm大神说可以用块状链表写...但是我不会...写了个splay.... 先离散化 , 然后splay结点加个min维护最小值 , 就可以了... ( ps BZOJ 3506 题意一样 , 双倍经 ...

  8. bzoj 1552: [Cerc2007]robotic sort

    1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1198  Solved: 457[Submit] ...

  9. 【LeetCode】147. Insertion Sort List 解题报告(Python)

    [LeetCode]147. Insertion Sort List 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: h ...

随机推荐

  1. OpenGL红宝书第一个例子:绘制两个三角形

    1. 环境配置 在这里不在做环境配置的说明,因为网上可以找到很多类似的教程,如果有需要可以@我,我也希望能帮到大家,其它的不说了,先上我的代码 2. 第一个程序代码 创建LoadShader.h #p ...

  2. Swift 学习笔记 (三) 之循环引用浅析

    原创:转载请注明出处 110.自动引用计数实践 下面的例子展示了自动引用计数的工作机制.例子以一个简单的Person类开始,并定义了一个叫name的常量属性: class Person {     l ...

  3. UIImageView 浅析

    UIImageView summary UIImageView极其常用,功能比较专一:显示图片 pooperty @property(nonatomic,retain) UIImage *image; ...

  4. HDU - 5234 Happy birthday

    Problem Description Today is Gorwin’s birthday. So her mother want to realize her a wish. Gorwin say ...

  5. 使用log4j无法输出日志

    前段时间在项目的过程中使用log4j来输出日志,但是在一个项目里我明明已经在src/main/resource目录下创建了log4j.properties.具体配置如下: log4j.rootLogg ...

  6. 微信小程序页面-页面跳转失败WAService.js:3 navigateTo:fail url not in app.json

    微信小程序新建页面的要素一是新建的文件名称和其子文件的名称最好一致,不然容易出问题,在小程序页面跳转中如果出现WAService.js:3 navigateTo:fail url not in app ...

  7. vbs 解析html文档的方法

    vbs 解析html文档的方法(htmlfile) 投稿:mdxy-dxy 字体:[增加 减小] 类型:转载 时间:2014-06-18我要评论 关于VBS采集,网上流行比较多的方法都是正则,其实 h ...

  8. php csv操作

    csv的写入数据: $data = array( array('qq号','登录时间','名称'), array('123456','2012-08-21 15:21:10'.chr(1),'我是来测 ...

  9. 别说你不知道java中的包装类,wrapper type,以及容易在自动拆箱中出现的问题

    很多时候,会有人问你,你知道什么是包装类吗? 或者高端一点问你你知道,wrapper type,是什么吗? 然后你就懵逼了,学了java很多时候都不知道这是啥. 其实问你的人,可能只是想问你,java ...

  10. MQ日常维护操作手册

    假设队列管理器为QMgrName,以下所有使用QMgrName的地方您都可以替换成您维护的mq队列管理器名称. 一.MQ的启动与停止 用root用户启/停需要root用户包含在mqm组中. 1.MQ的 ...