首页 > 代码库 > hdu 1890 Robotic Sort(splay 区间反转+删点)

hdu 1890 Robotic Sort(splay 区间反转+删点)

题目链接:hdu 1890 Robotic Sort

题意:

给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次。

题解:

典型的splay区间翻转+删点。

我们把数据排序,然后记录一下每个数原来的位置,然后splay建树的时候用原来的位置来对应,这样val[i].second就直接是这个数在splay中的那个节点。

(当然你也可以普通建树,然后手动记录位置)。

然后我们把要找的那个数对应的节点旋转到根,然后根左边的size+i就是当前数的答案,然后翻转一下前面的数,再删除根。

技术分享
 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 
 5 const int N=1e5+7;
 6 int n,a[N],size[N],ch[N][2],f[N],tot,root;bool rev[N];
 7 pair<int,int>val[N];
 8 
 9 void rev1(int x){if(!x)return;swap(ch[x][0],ch[x][1]);rev[x]^=1;}
10 
11 void pb(int x){
12     if(rev[x]){
13         rev1(ch[x][0]);
14         rev1(ch[x][1]);
15         rev[x]=0;
16     }
17 }
18 
19 void up(int x){
20     size[x]=1;
21     if(ch[x][0])size[x]+=size[ch[x][0]];
22     if(ch[x][1])size[x]+=size[ch[x][1]];
23 }
24 
25 void rotate(int x){
26     int y=f[x],w=ch[y][1]==x;
27     ch[y][w]=ch[x][w^1];
28     if(ch[x][w^1])f[ch[x][w^1]]=y;
29     if(f[y]){
30         int z=f[y];
31         if(ch[z][0]==y)ch[z][0]=x;
32         if(ch[z][1]==y)ch[z][1]=x;
33     }
34     f[x]=f[y];ch[x][w^1]=y;f[y]=x;up(y);
35 }
36 
37 void splay(int x,int w){
38     int s=1,i=x,y;a[1]=x;
39     while(f[i])a[++s]=i=f[i];
40     while(s)pb(a[s--]);
41     while(f[x]!=w){
42         y=f[x];
43         if(f[y]!=w){if((ch[f[y]][0]==y)^(ch[y][0]==x))rotate(x);else rotate(y);}
44         rotate(x);
45     }
46     if(!w)root=x;
47     up(x);
48 }
49 
50 void newnode(int &r,int fa,int k)
51 {
52     r=k,f[r]=fa,rev[r]=0,ch[r][0]=ch[r][1]=0;
53 }
54 
55 void build(int &x,int l,int r,int fa){
56     int mid=(l+r)>>1;
57     newnode(x,fa,mid);
58     if(l<mid)build(ch[x][0],l,mid-1,x);
59     if(r>mid)build(ch[x][1],mid+1,r,x);
60     up(x);
61     return;
62 }
63 
64 int getmax(int x)
65 {
66     pb(x);
67     while(ch[x][1])x=ch[x][1],pb(x);
68     return x;
69 }
70 
71 void delroot()
72 {
73     if(ch[root][0])
74     {
75         int m=getmax(ch[root][0]);
76         splay(m,root);
77         ch[m][1]=ch[root][1];
78         f[ch[root][1]]=m;
79         root=m,f[m]=0,up(m);
80     }else root=ch[root][1],f[root]=0;
81 }
82 
83 int main(){
84     while(scanf("%d",&n),n)
85     {
86         F(i,1,n)scanf("%d",&val[i].first),val[i].second=i;
87         sort(val+1,val+1+n),build(root,1,n,0);
88         F(i,1,n-1)
89         {
90             splay(val[i].second,0);
91             rev1(ch[root][0]);
92             printf("%d ",i+size[ch[root][0]]);
93             delroot();
94         }
95         printf("%d\n",n);    
96     }
97     return 0;
98 }
View Code

 

hdu 1890 Robotic Sort(splay 区间反转+删点)