首页 > 代码库 > BZOJ1552: [Cerc2007]robotic sort

BZOJ1552: [Cerc2007]robotic sort

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 328  Solved: 134
[Submit][Status]

Description

Input

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

Output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),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

HINT

 

Source

HNOI2009集训Day6

题解:
每次写splay都要调2h。。。
rever操作很好写,如果一个数已经到了该到的位置我们就可以删掉它了。所以我们主要得找最小数所在的位置。
rk?pos?这个一定要搞清楚
我记录了一个最小值以及最小值在子树内的rk,然后就可以更新了。
时刻注意是rk还是pos
代码:
  1 #include<cstdio>  2 #include<cstdlib>  3 #include<cmath>  4 #include<cstring>  5 #include<algorithm>  6 #include<iostream>  7 #include<vector>  8 #include<map>  9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 200000+5 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define mod 1000000007 23 using namespace std; 24 inline int read() 25 { 26     int x=0,f=1;char ch=getchar(); 27     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} 28     while(ch>=0&&ch<=9){x=10*x+ch-0;ch=getchar();} 29     return x*f; 30 } 31 int n,rt,t1,t2,a[maxn],b[maxn],fa[maxn],c[maxn][2],mi[maxn][2],s[maxn]; 32 bool rev[maxn]; 33 inline void pushup(int x) 34 { 35     int l=c[x][0],r=c[x][1]; 36     s[x]=s[l]+s[r]+1; 37     mi[x][0]=a[x];mi[x][1]=s[l]+1; 38     if(mi[x][0]>mi[l][0])mi[x][0]=mi[l][0],mi[x][1]=mi[l][1]; 39     if(mi[x][0]>mi[r][0])mi[x][0]=mi[r][0],mi[x][1]=s[l]+1+mi[r][1]; 40 } 41 inline void rotate(int x,int &k) 42 { 43     //cout<<x<<‘ ‘<<k<<" AAAAAA"<<endl; 44     int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1; 45     if(y!=k)c[z][c[z][1]==y]=x;else k=x; 46     fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 47     c[y][l]=c[x][r];c[x][r]=y; 48     pushup(y);pushup(x); 49 } 50 inline void splay(int x,int &k) 51 { 52     while(x!=k) 53     { 54         int y=fa[x],z=fa[y]; 55         if(y!=k) 56         { 57             if(c[z][0]==y^c[y][0]==x)rotate(x,k);else rotate(y,k); 58         } 59         rotate(x,k); 60     } 61 } 62 inline void rever(int x) 63 { 64     if(!x)return; 65     rev[x]^=1; 66     swap(c[x][0],c[x][1]); 67     mi[x][1]=s[x]+1-mi[x][1]; 68 } 69 inline void pushdown(int x) 70 { 71     if(!x)return; 72     if(!rev[x])return; 73     rever(c[x][0]);rever(c[x][1]); 74     rev[x]=0; 75 } 76 inline int find(int x,int k) 77 { 78     pushdown(x); 79     int l=c[x][0],r=c[x][1]; 80     if(s[l]+1==k)return x; 81     else if(s[l]>=k)return find(l,k); 82     else return find(r,k-s[l]-1); 83 } 84 inline void split(int l,int r) 85 { 86     t1=find(rt,l);t2=find(rt,r); 87     splay(t1,rt);splay(t2,c[t1][1]); 88 } 89 inline void build(int l,int r,int f) 90 { 91     if(l>r)return; 92     int x=(l+r)>>1; 93     fa[x]=f;c[f][x>f]=x; 94     if(l==r){s[x]=1;mi[x][0]=a[x];mi[x][1]=1;return;} 95     build(l,x-1,x);build(x+1,r,x); 96     pushup(x); 97 } 98 inline bool cmp(int x,int y){return a[x]==a[y]?x<y:a[x]<a[y];} 99 int main()100 {101     freopen("input.txt","r",stdin);102     freopen("output.txt","w",stdout);103     n=read();104     for2(i,2,n+1)a[i]=read(),b[i]=i;105     sort(b+2,b+n+2,cmp);106     for2(i,2,n+2)a[b[i]]=i;107     a[1]=a[n+2]=n+n;mi[0][0]=inf;108     build(1,n+2,0);rt=(1+n+2)>>1;109     for1(i,n)110     {111         //cout<<mi[rt][1]<<endl;112         int x=find(rt,mi[rt][1]);113         printf("%d",(n-(s[rt]-mi[rt][1]-1)));114         if(i!=n)printf(" ");115         //cout<<x<<endl;116         split(1,mi[rt][1]+1);117         rever(c[t2][0]);118         pushup(t2);pushup(t1);119         split(1,3);120         //cout<<"AAAAAAA"<<‘ ‘<<a[c[t2][0]]<<endl;121         c[t2][0]=0;122         pushup(t2);pushup(t1);  123     }124     printf("\n");125     return 0;126 }
View Code

刚开始没离散化WA了感觉是调不出来了。。。

BZOJ1552: [Cerc2007]robotic sort