博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3506: [Cqoi2014]排序机械臂
阅读量:5221 次
发布时间:2019-06-14

本文共 3375 字,大约阅读时间需要 11 分钟。

额,$BZOJ$上没有题面。。。

本蒟蒻表示没钱氪金。。。

这里附上洛谷的题面:

题目描述

为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。

它遵循一个简单的排序规则,第一次操作找到高度最低的物品的位置 $P_1$ ,并把左起第一个物品至 $P_1$ 间的物品 (即区间 $[1,P_1]$间的物品) 反序;第二次找到第二低的物品的位置 $P_2$ ,并把左起第二个至 $P_2$ 间的物品 (即区间 $[2,P_2]$ 间的物品) 反序……最终所有的物品都会被排好序。

样例说明

上图给出有六个物品的示例,第一次操作前,高度最低的物品在位置 $4$ ,于是把第一至第四的物品反序;第二次操作前,第二低的物品在位罝六,于是把第二至六的物品反序……

你的任务便是编写一个程序,确定一个操作序列,即每次操作前第$ i$ 低的物品所在位置$ P_i$,以便机械臂工作。

需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。

输入输出格式

输入格式:

第一行包含正整数n,表示需要排序的物品数星。

第二行包含n个空格分隔的整数$P_i$,表示每个物品的高度。

输出格式:

输出一行包含n个空格分隔的整数Pi。

输入输出样例

输入样例#1: 
63 4 5 1 6 2
输出样例#1: 
4 6 4 5 6 6

说明

N<=100000

Pi<=10^7


题解Here!

看到区间翻转——区间神器$Splay$!

但是!高度是无序的,而$Splay$是有序的,怎么办呢?

我们可以用结构体存高度与 下标,然后排序。

于是高度就可以丢一边了。。。

具体看代码中的$splay::reverse$ 。

注意:

  1. 头尾设两个哨兵节点。
  2. $splay$每次都要$pushdown$一次(巨坑)!

附代码:

#include
#include
#include
#define MAXN 100010#define MAX 999999999using namespace std;int n,size=1,root=0;struct node{ int x,id;}b[MAXN];namespace splay{ struct Splay{ int f,s,flag,son[2]; int v; }a[MAXN]; inline void clean(int rt){ a[rt].son[0]=a[rt].son[1]=a[rt].f=a[rt].s=a[rt].flag=a[rt].v=0; } inline void pushup(int rt){ if(!rt)return; a[rt].s=a[a[rt].son[0]].s+a[a[rt].son[1]].s+1; } inline void pushdown(int rt){ if(!rt||!a[rt].flag)return; a[a[rt].son[0]].flag^=1;a[a[rt].son[1]].flag^=1;a[rt].flag^=1; swap(a[rt].son[0],a[rt].son[1]); } inline void turn(int rt,int k){ int x=a[rt].f,y=a[x].f; a[x].son[k^1]=a[rt].son[k]; if(a[rt].son[k])a[a[rt].son[k]].f=x; a[rt].f=y; if(y)a[y].son[a[y].son[1]==x]=rt; a[x].f=rt; a[rt].son[k]=x; pushup(x);pushup(rt); } void splay(int rt,int ancestry){ while(a[rt].f!=ancestry){ int x=a[rt].f,y=a[x].f; pushdown(y);pushdown(x);pushdown(rt); if(y==ancestry)turn(rt,a[x].son[0]==rt); else{ int k=a[y].son[0]==x?1:0; if(a[x].son[k]==rt){turn(rt,k^1);turn(rt,k);} else{turn(x,k);turn(rt,k);} } } if(ancestry==0)root=rt; } inline int newnode(int x){ int rt=size++; clean(rt); a[rt].v=x;a[rt].s=1; return rt; } int buildtree(int l,int r){ if(l>r)return 0; int mid=l+r>>1,lson=0,rson=0; lson=buildtree(l,mid-1); int rt=newnode(b[mid].x); rson=buildtree(mid+1,r); a[rt].son[0]=lson; a[rt].son[1]=rson; if(lson)a[lson].f=rt; if(rson)a[rson].f=rt; pushup(rt); return rt; } int kth(int rt,int k){ if(a[rt].s
a[y].s+1){ k-=a[y].s+1; rt=a[rt].son[1]; } else if(k<=a[y].s)rt=y; else return rt; } } inline void reverse(int i){ splay(b[i].id+1,0); int s=a[a[root].son[0]].s; printf("%d ",s); int front=kth(root,i),next=kth(root,s+2); splay(front,0);splay(next,front); a[a[next].son[0]].flag^=1; }}inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w;}bool cmp(const node &x,const node &y){ if(x.x==y.x)return x.id

 

转载于:https://www.cnblogs.com/Yangrui-Blog/p/9940392.html

你可能感兴趣的文章
HTML标签_1
查看>>
jsp组成元素
查看>>
排序算法(转)
查看>>
windows自带的可生成各种数据库连接字符串工具打开方法
查看>>
Python命名规范
查看>>
滚动条
查看>>
程序员的自我修养九Windows下的动态链接
查看>>
Codeforces Round #361 (Div. 2)
查看>>
细说WebSocket - Node篇
查看>>
Extjs控件之 grid打印功能
查看>>
枚举类型(不常用)递归
查看>>
minggw 安装
查看>>
Jquery操作cookie,实现简单的记住用户名的操作
查看>>
[BZOJ1196][HNOI2006]公路修建问题 二分答案+最小生成树
查看>>
【原创】大数据基础之Zookeeper(4)应用场景
查看>>
静态变量数组实现LRU算法
查看>>
中文系统 上传file的input显示英文
查看>>
比callback更简洁的链式执行promise
查看>>
android permission
查看>>
【译】在Asp.Net中操作PDF - iTextSharp - 使用字体
查看>>