AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1552

【分析】

  这题哇!又有翻转操作...每次要输出第几个?是吧...

  所以又要用Splay了。

  可是这道题有创新的地方,因为又有数值上的有序[取最小值],又有位置上的有序[翻转和求第几个]

  可是毕竟最小值的操作会简单很多...所以我们采用的是将位置作为Splay的节点信息。

  那么怎么快速得到最小值的位置呢?当然就是常用的push_up了...向上更新就好了。

  这里一定要注意题目所说:按照刚开始给你的顺序排序,在实现中就是数组的下标了,每次还需要比较两边最优值的大小和下标。

  然后每次选出最小值,将其转到树根,输出其左子树的大小+已经删去的最小值数目,然后将它删去,从左子树中选一个最右边的节点翻到顶上,作为新的节点。

  大致过程就是这样啦...【表示都是笔者想出来的...很开心啊...只是速度还是没有某人快啊...】

  

#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; inline int in(){
int x=,f=;char ch=getchar();
while((ch>'' || ch<'') && ch!='-') ch=getchar();
if(ch=='-') f=-,ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return x*f;
} const int maxn=;
const int INF=0x7f7f7f7f; struct Node{
int ch[],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[],s[x].ch[]);
s[s[x].ch[]].rv^=,s[s[x].ch[]].rv^=;
s[x].rv=;
}
}
void update(int x){
s[x].sz=s[s[x].ch[]].sz+s[s[x].ch[]].sz+;
s[x].mn=s[x].dt,s[x].lc=x;
int l,r;l=s[x].ch[],r=s[x].ch[];
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 ;
int mid=(l+r)>>;
s[mid].ch[]=build(l,mid-);
s[mid].ch[]=build(mid+,r);
if(s[mid].ch[]) s[s[mid].ch[]].f=mid;
if(s[mid].ch[]) s[s[mid].ch[]].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[]]=x;
s[y].ch[k]=s[x].ch[k^];
if(s[x].ch[k^]) s[s[x].ch[k^]].f=y;
s[y].f=x,s[x].ch[k^]=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[]);
else{
int z=s[y].f;
if(y==s[z].ch[]){
if(x==s[y].ch[]) Rotate(y,),Rotate(x,);else Rotate(x,),Rotate(x,);}
else{
if(x==s[y].ch[]) Rotate(y,),Rotate(x,);else Rotate(x,),Rotate(x,);}
}
}
if(!gf) rt=x;
} int Find_right(int x){
int p=x,f=-;
while(p){
push_down(p);
f=p;p=s[f].ch[];
}
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_JUDGE
freopen("1552.in","r",stdin);
freopen("1552.out","w",stdout);
#endif n=in();
for(int i=;i<=n;i++) a[i]=in();
s[].mn=INF;s[].lc=-;
rt=build(,n);
int x;
for(int i=;i<=n;i++){
up_push_down(s[rt].lc);
Splay(s[rt].lc,);
printf("%d",s[s[rt].ch[]].sz+i);
if(i!=n) printf(" ");
s[s[rt].ch[]].rv^=;
if(!s[rt].ch[]){
s[s[rt].ch[]].f=;rt=s[rt].ch[];
}
else{
x=Find_right(s[rt].ch[]);
Splay(x,rt);
s[x].f=;
s[x].ch[]=s[rt].ch[];
if(s[rt].ch[])
s[s[rt].ch[]].f=x;
update(x);rt=x;
}
}
return ;
}

BZOJ 1552/1506 [Cerc2007]robotic sort的更多相关文章

  1. 【BZOJ】1552/3506 [Cerc2007]robotic sort

    [算法]splay [题解] splay维护序列,用权值(离散化)作为编号.每次找第i小的话直接找对应编号splay即可. 但是这样splay没有下传翻转标记?直接暴力找到路径然后从根到改结点push ...

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

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

  3. bzoj 1552: [Cerc2007]robotic sort

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

  4. [BZOJ1552][Cerc2007]robotic sort

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

  5. 【BZOJ1552】[Cerc2007]robotic sort Splay

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

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

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

  7. [Cerc2007]robotic sort

    splay区间反转练手题 #include <iostream> #include <cstdio> #include <algorithm> using name ...

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

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

  9. 1552: [Cerc2007]robotic sort

    这道题用splay写 先离散化数据保证按题目所述顺序来写 按原序作为键值建树 维护区间最小值去跑 每次将i的位置 和 n的位置x和y找出来后 将x旋转到root y旋转到x的有儿子 这时y的左子树就是 ...

随机推荐

  1. 实现Win7远程桌面关机和重启

    通过远程桌面控制Win7系统时,菜单中没有关机和重启按钮, 1.方法1 关机 shutdown -s -t 0重启 shutdown -r -t 0 可以先打开运行框(Win+R键),输入上述命令即可 ...

  2. Python 字典(Dictionary)操作详解

    Python 字典(Dictionary)的详细操作方法. Python字典是另一种可变容器模型,且可存储任意类型对象,如字符串.数字.元组等其他容器模型. 一.创建字典 字典由键和对应值成对组成.字 ...

  3. 一款jQuery特效编写的大度宽屏焦点图切换特效

    一款jQuery编写的大度宽屏焦点图切换特效 焦点图显示区域有固定的宽度,当前显示宽度之外是一个半透明层显示的其它的焦点图片, 最好的是,此特效兼容IE6以及其它浏览器. 适用浏览器:IE6.IE7. ...

  4. Ubuntu10.10的网络配置

    有一阵子着实对Ubuntu的网络配置很迷惑,耐下心来仔细上网找了找,有点小心得,总结一下. 先说下大概的配置过程,再去细究一些情况. 一.配置大概分三类:通过配置文件配置.通过命令配置.通过图形化的网 ...

  5. web app 开发

    去除手机浏览器标签默认高亮边框 -webkit-tap-highlight-color 属性 属性描述:这个属性可以指设置透明度.如果未设置透明度,iOS上的Safari会给予颜色一个默认的透明度.把 ...

  6. ASP.NET MVC5学习笔记之Controller执行ControllerDescriptor和ActionDescriptor

    一. ControllerDescriptor说明 ControllerDescriptor是一个抽象类,它定义的接口代码如下: public abstract class ControllerDes ...

  7. 如何排查java.lang.NoSuchMethodError错误

    今天碰到一个java.lang.NoSuchMethodException的异常.基本解决思路是: 1.检查类所在jar包的版本是否正确. 2.检查是否有jar包冲突,比如加载了多个版本的xxx.ja ...

  8. UCOS2_STM32F1移植详细过程(四)

    Ⅰ.概述 上一篇文章是讲述uC/OS-II Ports下面os_cpu_a.asm.os_cpu_c.c和os_cpu.h文件底层端口代码的移植(修改)和说明,接着上一篇文章来讲述关于UCOS移植应用 ...

  9. 002-python基础-hello-world

    python hello.py 时,明确的指出 hello.py 脚本由 python 解释器来执行. 如果想要类似于执行shell脚本一样执行python脚本,例: ./hello.py ,那么就需 ...

  10. (转)python文件操作 seek(),tell()

    seek():移动文件读取指针到指定位置 tell():返回文件读取指针的位置 seek()的三种模式: (1)f.seek(p,0)  移动当文件第p个字节处,绝对位置 (2)f.seek(p,1) ...