BZOJ 1552: [Cerc2007]robotic sort/3506: [Cqoi2014]排序机械臂 splay

来源:互联网 发布:双拼net域名行情 编辑:程序博客网 时间:2024/05/17 02:11

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1273  Solved: 488
[Submit][Status][Discuss]

Description

Input

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

Output

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

Sample Input

6
3 4 5 1 6 2

Sample Output

4 6 4 5 6 6


发现自己又不会写splay了 GG

这题很水啊。。。我竟然硬是搞了两个小时。。。

只需要维护子树内权值最小的点的标号就好了


最开始打挂 然后狂调 最后越调越乱

无奈的重构代码

最后 这成为了我有史以来写的最好的一棵splay


#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<set>#include<map>using namespace std;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=100100,inf=0X3f3f3f3f;struct node{int val,pos;friend bool operator <(const node &x,const node &y){return x.val==y.val?x.pos<y.pos:x.val<y.val;}}p[N];inline bool cmp(const node &x,const node &y){return x.pos<y.pos;}int n;int root,ch[N][2],fa[N],V[N],mn[N],size[N];bool rev[N];int pos[N];inline void pushup(int k){size[k]=size[ch[k][0]]+size[ch[k][1]]+1;mn[k]=k;if(ch[k][0]&&V[mn[ch[k][0]]]<V[mn[k]])mn[k]=mn[ch[k][0]];if(ch[k][1]&&V[mn[ch[k][1]]]<V[mn[k]])mn[k]=mn[ch[k][1]];}inline void pushdown(int k){if(rev[k]){rev[k]=0;swap(ch[k][0],ch[k][1]);rev[ch[k][0]]^=1;rev[ch[k][1]]^=1;}}inline void getdown(int k){if(fa[k])getdown(fa[k]);pushdown(k);}int build(int l,int r,int pre){if(l>r)return 0;int mid=(l+r)>>1;fa[mid]=pre;V[mid]=p[mid].val;ch[mid][0]=build(l,mid-1,mid);ch[mid][1]=build(mid+1,r,mid);pushup(mid);return mid;}inline int find(int rk){int k=root;while(rk){pushdown(k);if(size[ch[k][0]]>=rk)k=ch[k][0];else if(size[ch[k][0]]+1<rk)rk-=size[ch[k][0]]+1,k=ch[k][1];else return k;}}inline void rotate(int x,int &k){int y=fa[x],z=fa[y],l,r;l=(ch[y][1]==x);r=l^1;y==k?k=x:ch[z][ch[z][1]==y]=x;fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;ch[y][l]=ch[x][r];ch[x][r]=y;pushup(y);pushup(x);}void splay(int x,int &k){getdown(x);int y,z;while(x!=k){y=fa[x],z=fa[y];if(y!=k){if((ch[y][0]==x)^(ch[z][0]==y))rotate(x,k);else rotate(y,k);}rotate(x,k);}}int query_mn(int x,int y){x=find(x);y=find(y+2);splay(x,root);splay(y,ch[x][1]);return mn[ch[y][0]];}void rever(int x,int y){x=find(x),y=find(y+2);splay(x,root);splay(y,ch[x][1]);rev[ch[y][0]]^=1;}int main(){n=read();register int i,x;p[1].val=p[n+2].val=inf;for(i=2;i<=n+1;++i)p[i].val=read(),p[i].pos=i;sort(p+2,p+2+n);for(i=2;i<=n+1;++i)p[i].val=i;sort(p+2,p+2+n,cmp);root=build(1,n+2,0);for(i=1;i<=n;++i){x=query_mn(i,n);splay(x,root);print(size[ch[x][0]]);if(i^n)putchar(' ');rever(i,size[ch[x][0]]);}puts("");return 0;}/*63 4 5 1 6 24 6 4 5 6 6*/

阅读全文
0 0
原创粉丝点击