Description
Solution
一道很水很水的题,splay树保存一个最小值,每次查找最小值所在的位置,旋转到根,输出它在第几位。然后将它之前的节点打上翻转标记,维护一下即可。
注意这道题要先排序,因为翻转操作之后就不知到它原来的位置了。
1 //Never forget why you start 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #define ll(x) bst[x].child[0] 9 #define rr(x) bst[x].child[1] 10 #define son(x,t) bst[x].child[t] 11 #define inf (2147483647) 12 using namespace std; 13 int root,n,cnt; 14 struct point{ 15 int x,id; 16 }a[100005]; 17 bool cmp1(const point a,const point b){ 18 return a.x<b.x||(a.x==b.x&&a.id<b.id); 19 } 20 bool cmp2(const point a,const point b){ 21 return a.id<b.id; 22 } 23 struct BST{ 24 int child[2],fa,mmin,x,size,lazy; 25 }bst[100005]; 26 void push_up(int root){ 27 int l=ll(root),r=rr(root); 28 bst[root].mmin=bst[root].x; 29 if(l)bst[root].mmin=min(bst[root].mmin,bst[l].mmin); 30 if(r)bst[root].mmin=min(bst[root].mmin,bst[r].mmin); 31 bst[root].size=bst[l].size+bst[r].size+1; 32 } 33 void push_down(int root){ 34 int l=ll(root),r=rr(root); 35 if(bst[root].lazy){ 36 if(l)bst[l].lazy^=1; 37 if(r)bst[r].lazy^=1; 38 bst[root].lazy^=1; 39 swap(ll(root),rr(root)); 40 } 41 } 42 void rotate(int r,int t){ 43 int fa=bst[r].fa; 44 son(fa,!t)=son(r,t);bst[son(r,t)].fa=fa; 45 son(bst[fa].fa,son(bst[fa].fa,1)==fa)=r;bst[r].fa=bst[fa].fa; 46 son(r,t)=fa;bst[fa].fa=r; 47 push_up(fa); 48 push_up(r); 49 } 50 void splay(int r,int goal){ 51 int fa=bst[r].fa; 52 while(fa!=goal){ 53 if(bst[fa].fa==goal)rotate(r,son(fa,0)==r); 54 else{ 55 int t=son(bst[fa].fa,0)==fa; 56 if(son(fa,t)==r)rotate(r,!t),rotate(r,t); 57 else rotate(fa,t),rotate(r,t); 58 } 59 fa=bst[r].fa; 60 } 61 if(goal==0)root=r; 62 } 63 int search(int root){ 64 push_down(root); 65 if(bst[root].mmin==bst[ll(root)].mmin)return search(ll(root)); 66 if(bst[root].mmin==bst[root].x)return root; 67 if(bst[root].mmin==bst[rr(root)].mmin)return search(rr(root)); 68 } 69 int find(int root,int k){ 70 push_down(root); 71 int y=bst[ll(root)].size; 72 if(y+1==k)return root; 73 else if(y>=k)return find(ll(root),k); 74 else return find(rr(root),k-y-1); 75 } 76 void build(int &root,int left,int right,int fa){ 77 int mid=(left+right)>>1; 78 root=++cnt; 79 bst[root].fa=fa; 80 if(left==right){ 81 bst[root].x=bst[root].mmin=a[left].x; 82 bst[root].size=1; 83 return; 84 } 85 if(left<mid)build(ll(root),left,mid-1,root); 86 if(mid<right)build(rr(root),mid+1,right,root); 87 bst[root].x=a[mid].x;bst[root].size=1; 88 push_up(root); 89 } 90 int split(int l,int r){ 91 l--;r++; 92 int x=find(root,l),y=find(root,r); 93 splay(x,0); 94 splay(y,x); 95 return ll(y); 96 } 97 void delet(int pos){ 98 splay(pos,0); 99 int x=find(root,bst[ll(pos)].size); 100 int y=find(root,bst[ll(pos)].size+2); 101 splay(x,0); 102 splay(y,x); 103 son(y,0)=0; 104 bst[pos].fa=0; 105 push_up(y); 106 push_up(x); 107 } 108 int main(){ 109 int i,j; 110 scanf("%d",&n); 111 for(i=1;i<=n;i++) 112 scanf("%d",&a[i+1].x),a[i+1].id=i; 113 sort(a+2,a+n+2,cmp1); 114 for(i=1;i<=n;i++) 115 a[i+1].x=i; 116 sort(a+2,a+n+2,cmp2); 117 n+=2; 118 a[1].x=a[n].x=inf; 119 bst[0].x=bst[0].mmin=inf; 120 bst[0].size=0; 121 build(root,1,n,0); 122 for(i=0;i<=n-3;i++){ 123 int x=split(2,n-1-i); 124 x=search(x); 125 splay(find(root,1),0); 126 splay(x,root); 127 bst[ll(x)].lazy^=1; 128 printf("%d ",bst[ll(x)].size+1+i); 129 delet(x); 130 } 131 return 0; 132 }