1552: [Cerc2007]robotic sort
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 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
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;
}
/*
6
3 4 5 1 6 2
4 6 4 5 6 6
*/