BZOJ 1552/1506 [Cerc2007]robotic sort
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1552
【分析】
这题哇!又有翻转操作...每次要输出第几个?是吧...
所以又要用Splay了。
可是这道题有创新的地方,因为又有数值上的有序[取最小值],又有位置上的有序[翻转和求第几个]
可是毕竟最小值的操作会简单很多...所以我们采用的是将位置作为Splay的节点信息。
那么怎么快速得到最小值的位置呢?当然就是常用的push_up了...向上更新就好了。
这里一定要注意题目所说:按照刚开始给你的顺序排序,在实现中就是数组的下标了,每次还需要比较两边最优值的大小和下标。
然后每次选出最小值,将其转到树根,输出其左子树的大小+已经删去的最小值数目,然后将它删去,从左子树中选一个最右边的节点翻到顶上,作为新的节点。
大致过程就是这样啦...【表示都是笔者想出来的...很开心啊...只是速度还是没有某人快啊...】
![](/assets/blank.gif)
![](/assets/blank.gif)
#include<cstdio> #include<cstring> #include<algorithm>using namespace std;inline int in(){int x=0,f=1;char ch=getchar();while((ch>'9' || ch<'0') && ch!='-') ch=getchar();if(ch=='-') f=-1,ch=getchar();while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x*f; }const int maxn=100010; const int INF=0x7f7f7f7f;struct Node{int ch[2],f;int sz,mn,lc,dt;bool rv; }s[maxn];int n,rt; int a[maxn];void push_down(int x){if(s[x].rv){swap(s[x].ch[0],s[x].ch[1]);s[s[x].ch[0]].rv^=1,s[s[x].ch[1]].rv^=1;s[x].rv=0;} } void update(int x){s[x].sz=s[s[x].ch[0]].sz+s[s[x].ch[1]].sz+1;s[x].mn=s[x].dt,s[x].lc=x;int l,r;l=s[x].ch[0],r=s[x].ch[1];if((s[l].mn<s[x].mn) || (s[l].mn==s[x].mn && s[l].lc<s[x].lc)) s[x].mn=s[l].mn,s[x].lc=s[l].lc;if((s[r].mn<s[x].mn) || (s[r].mn==s[x].mn && s[r].lc<s[x].lc)) s[x].mn=s[r].mn,s[x].lc=s[r].lc; }int build(int l,int r){if(l>r) return 0;int mid=(l+r)>>1;s[mid].ch[0]=build(l,mid-1);s[mid].ch[1]=build(mid+1,r);if(s[mid].ch[0]) s[s[mid].ch[0]].f=mid;if(s[mid].ch[1]) s[s[mid].ch[1]].f=mid;s[mid].dt=a[mid];update(mid);return mid; }void Rotate(int x,int k){int y=s[x].f;s[x].f=s[y].f;if(s[y].f) s[s[y].f].ch[y==s[s[y].f].ch[1]]=x;s[y].ch[k]=s[x].ch[k^1];if(s[x].ch[k^1]) s[s[x].ch[k^1]].f=y;s[y].f=x,s[x].ch[k^1]=y;update(y),update(x); }void Splay(int x,int gf){int y;while(s[x].f!=gf){y=s[x].f;if(s[y].f==gf) Rotate(x,x==s[y].ch[1]);else{int z=s[y].f;if(y==s[z].ch[0]){if(x==s[y].ch[0]) Rotate(y,0),Rotate(x,0);else Rotate(x,1),Rotate(x,0);}else{if(x==s[y].ch[1]) Rotate(y,1),Rotate(x,1);else Rotate(x,0),Rotate(x,1);}}}if(!gf) rt=x; }int Find_right(int x){int p=x,f=-1;while(p){push_down(p);f=p;p=s[f].ch[1];}return f; }int st[maxn],tp;void up_push_down(int x){int p=x;while(p)st[++tp]=p,p=s[p].f;while(tp)push_down(st[tp--]); }int main(){ #ifndef ONLINE_JUDGEfreopen("1552.in","r",stdin);freopen("1552.out","w",stdout); #endifn=in();for(int i=1;i<=n;i++) a[i]=in();s[0].mn=INF;s[0].lc=-1;rt=build(1,n);int x;for(int i=1;i<=n;i++){up_push_down(s[rt].lc);Splay(s[rt].lc,0);printf("%d",s[s[rt].ch[0]].sz+i);if(i!=n) printf(" ");s[s[rt].ch[0]].rv^=1;if(!s[rt].ch[0]){s[s[rt].ch[1]].f=0;rt=s[rt].ch[1];}else{x=Find_right(s[rt].ch[0]);Splay(x,rt);s[x].f=0;s[x].ch[1]=s[rt].ch[1];if(s[rt].ch[1])s[s[rt].ch[1]].f=x;update(x);rt=x;}}return 0; }
View Code
转载于:https://www.cnblogs.com/Robert-Yuan/p/5087213.html
BZOJ 1552/1506 [Cerc2007]robotic sort相关推荐
- bzoj 1552: [Cerc2007]robotic sort bzoj 3506: [Cqoi2014]排序机械臂(splay区间翻转)
1552: [Cerc2007]robotic sort Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1206 Solved: 460 [Submi ...
- [bzoj1552][Cerc2007]robotic sort[bzoj3506][Cqoi2014]排序机械臂
非常垃圾的一道平衡树,结果被日了一天.很难受嗷嗷嗷 首先不得不说网上的题解让我这个本来就不熟悉平衡树的彩笔很难受--并不好理解. 还好Sinogi大佬非常的神,一眼就切掉了,而且用更加美妙的解法. 题 ...
- bzoj15523506 robotic sort
这道题提醒了我: 1.交之前要删文件 2.v不要打成mn 3.maintain的位置 4.pushdown pushdown pushdown 1 #include<cstdio> 2 # ...
- 【HDOJ】1890 Robotic Sort
伸展树伤不起啊,很容易wa,很容易T,很容易M. 1 /* 1890 */ 2 #include <iostream> 3 #include <string> 4 #inclu ...
- HDU - 1890 Robotic Sort(Splay-区间翻转+删除根节点)
题目链接:点击查看 题目大意:给出一个序列,初始时是乱序的,要求根据规则排序,规则是,遍历每一个点 i ,使得区间 [ i , a[ i ] ] 内的数翻转,a[ i ] 表示的是数列中第 i 大的数 ...
- BZOJ 4143: [AMPPZ2014]The Lawyer( sort )
水题... 排序搞出每天的会议有哪些, 然后再按照会议的开始时间和结束时间排序, 最晚开始的和最早结束的会议不是同一场而且最晚开始的时间>最早结束的会议就有可能方案 -------------- ...
- Robotic Sort
一.题目 点此看题 题目描述 通过一系列移动,将某些物品按顺序摆好.规定只能使用如下方式排序: 先找到编号最小的物品的位置P1,将区间[1,P1]反转,再找到编号第二小的物品的位置P2,将区间[2,P ...
- bzoj 4743: [Usaco2016 Dec]Robotic Cow Herd 线段树+二分答案
题意 有n个数集,每个数集里最多只有10个元素,现在从每个数集里面选数一个数,假设选出的数的和是p,给出k,问前k小的p的和. n,k<=100000 分析 首先二分答案lim,然后考虑如何找到 ...
- 【BZOJ3506】[CQOI2014] 排序机械臂(Splay)
点此看题面 大致题意: 给你\(n\)个数.第一次找到最小值所在位置\(P_1\),翻转\([1,P_1]\),第二次找到剩余数中最小值所在位置\(P_2\),翻转\([2,P_2]\),以此类推.求 ...
最新文章
- 从菜鸟到老司机,数据科学的17个必用数据集推荐
- android 点击网络图片大全,android查看网络图片的实现方法
- curl请求本地域名问题
- Delphi的“动态窗体”技术实际应用[网络摘抄]
- 类文件到虚拟机(类加载机制)
- css中float详解,CSS浮动属性Float详解?史上最全Float详解
- quantaxis中使用docker安装,出现的问题
- hnu 暑期实训之魔咒词典
- mysql 主备监控_mysql 主从备份监控slave状态nagios脚本
- ASP.NET MVC 分部视图
- Vue进阶(贰零陆):Vue 培训课件
- 矩阵谱分解的求解流程
- 单相半桥两电平电压型逆变器的正弦脉宽调制(SPWM)——Matlab程序
- 固态硬盘是什么接口_今天说事儿—固态硬盘接口,防你入坑
- 7-21 查验身份证 (15 分)
- 51单片机编译没错但proteus数码管仿真出现乱码的情况
- 【数据结构(25)】5.7 哈夫曼树及其应用
- 手机端mp4文件头前置检测,检测mp4视频文件头(moov box)是否在前面
- js通用判断指定日期是周几,是否是周六、周日
- js实现表单form提交前进行确认提示