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. [Java]_函数传参的疑惑与思考

    问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. void dfs(TreeNode node , int sum , ArrayList& ...

  2. ThinkPHP实现联动菜单;

    联动菜单,首先给你看看前端是怎么写的:

  3. Apache 多端口多站点配置实例

    分享下Apache多端口多站点的配置方法,配置apache服务器的朋友参考下. 配置httpd.conf 监听多个端口 复制代码代码如下: # Listen: Allows you to bind A ...

  4. javascript绑定时间 含(IE)

    script language = "javascript" type = "text/javascript"> function test(){ win ...

  5. python 小技巧(import模块、查询类继承关系、安装包)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在这里列举一些我使用Python时积累的小技巧.这些技巧是我在使用Python过程 ...

  6. 【原创】StickHeaderListView的简单实现,解决footerView问题

    1.前言: 前几天用了GitHub上se.emilsjolander.stickylistheaders这个组件,然后发现这个组件的listview不能添加footerView,加了footer后,滑 ...

  7. 通过Maven搭建Mybatis项目

    学习通过maven工程搭建Mybatis工程开启对M ybaits的学习总结之旅. 1.首先创建Maven工程. 2.在pom.xml文件中加入依赖的jar <!-- mybatis核心包 -- ...

  8. OC中NSDictionary(字典)、NSMutableDictionary(可变字典)、NSSet(集合)、NSMutableSet(可变集合)得常用方法

    字典用于保存具有映射关系数据的集合 一个key—value对认为是一个条目(entry),字典是存储key—value对的容器 与数组不同,字典靠key存取元素 key不能重复,value必须是对象 ...

  9. MVC 中使用log4net 打印重复日志解决方法

    最近在项目中引用log4net 来打印日志,会发现在同一时间点 打印重复记录: 详见图

  10. 修改一行代码提升 Postgres 性能 100 倍

    http://www.datadoghq.com/2013/08/100x-faster-postgres-performance-by-changing-1-line/ SELECT c.key,  ...