【BZOJ3223】 Tyvj 1729 文艺平衡树 Splay
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
5 3
1 3
1 3
1 4
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source
区间翻转,注意kth时和标记时下方标记,没了。
1 #include <cstdio> 2 #include <iostream> 3 #define N 100100 4 using namespace std; 5 struct SplayNode 6 { 7 SplayNode *fa,*ch[2]; 8 SplayNode(); 9 int data,num,size; 10 bool rev; 11 int chr() {return this==fa->ch[1];} 12 void updata() {size=ch[0]->size+ch[1]->size+1;} 13 void mark() {rev=rev^1;} 14 void push() 15 { 16 if (rev) 17 { 18 rev=rev^1;; 19 ch[0]->mark(); 20 ch[1]->mark(); 21 swap(ch[0],ch[1]); 22 } 23 } 24 }*null; 25 SplayNode::SplayNode() {fa=ch[0]=ch[1]=null; rev=0; size=0;} 26 int n,m; 27 int a[N]; 28 namespace Splay 29 { 30 SplayNode *Root; 31 SplayNode *Build(int l,int r) 32 { 33 if (l>r) return null; 34 int mid=(l+r)>>1; 35 SplayNode *R=new SplayNode; 36 R->data=a[mid]; 37 R->ch[0]=Build(l,mid-1); 38 R->ch[1]=Build(mid+1,r); 39 R->ch[0]->fa=R; 40 R->ch[1]->fa=R; 41 R->updata(); 42 return R; 43 } 44 void MakeTree() 45 { 46 null=new SplayNode; 47 *null=SplayNode(); 48 Root=Build(1,n); 49 } 50 void rotate(SplayNode *x) 51 { 52 SplayNode *r=x->fa; 53 if (r==null || x==null) return; 54 int t=x->chr(); 55 r->ch[t]=x->ch[t^1]; 56 r->ch[t]->fa=r; 57 if (r->fa==null) Root=x; 58 else r->fa->ch[r->chr()]=x; 59 x->fa=r->fa; 60 x->ch[t^1]=r; 61 r->fa=x; 62 x->updata(); 63 r->updata(); 64 } 65 void splay(SplayNode *x,SplayNode *y) 66 { 67 for (;x->fa!=y;rotate(x)) 68 if (x->fa->fa!=y) 69 if (x->fa->chr()==x->chr()) rotate(x->fa); 70 else rotate(x); 71 } 72 SplayNode *Kth(int k) 73 { 74 SplayNode *r=Root; 75 if (k<1 || k>n) return null; 76 while (r!=null) 77 { 78 r->push(); 79 if (k<=r->ch[0]->size) r=r->ch[0]; 80 else if (k==r->ch[0]->size+1) return r; 81 else 82 { 83 k-=r->ch[0]->size+1; 84 r=r->ch[1]; 85 } 86 } 87 return null; 88 } 89 void reverse(int l,int r) 90 { 91 SplayNode *q=Kth(l-1); 92 SplayNode *p=Kth(r+1); 93 if (q==null && p==null) 94 { 95 Root->mark(); 96 return; 97 } 98 if (q==null) 99 { 100 splay(p,null); 101 p->ch[0]->mark(); 102 return; 103 } 104 if (p==null) 105 { 106 splay(q,null); 107 q->ch[1]->mark(); 108 return; 109 } 110 q->push(); 111 splay(q,null); 112 p->push(); 113 splay(p,q); 114 p->ch[0]->mark(); 115 } 116 void dfs(SplayNode *x) 117 { 118 if (x==null) return; 119 x->push(); 120 dfs(x->ch[0]); 121 printf("%d ",x->data); 122 dfs(x->ch[1]); 123 } 124 125 } 126 int main() 127 { 128 scanf("%d%d",&n,&m); 129 for (int i=1;i<=n;i++) a[i]=i; 130 Splay::MakeTree(); 131 //Splay::dfs(Splay::Root); 132 // cout<<endl; 133 for (int i=1;i<=m;i++) 134 { 135 int x,y; 136 scanf("%d%d",&x,&y); 137 Splay::reverse(x,y); 138 // Splay::dfs(Splay::Root); 139 // cout<<endl; 140 } 141 Splay::dfs(Splay::Root); 142 return 0; 143 }
—Anime Otaku Save The World.