标签:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #include <utility> 7 #include <iomanip> 8 #include <string> 9 #include <cmath> 10 #include <queue> 11 #include <assert.h> 12 #include <map> 13 #include <ctime> 14 #include <cstdlib> 15 #define LOCAL 16 const int MAXN = 500000 + 10; 17 const int INF = 100000000; 18 const int SIZE = 450; 19 const int maxnode = 0x7fffffff + 10; 20 using namespace std; 21 int M; 22 struct SPLAY{ 23 struct Node{ 24 int val, size; 25 bool turn; 26 Node *ch[2], *parent; 27 28 /*Node(){//暂时不要构造函数,节约时间 29 val = 0; 30 size = 0; 31 turn = 0; 32 parent = ch[0] = ch[1] = NULL; 33 }*/ 34 int cmp(){ 35 if (parent->ch[0] == this) return 0; 36 else return 1; 37 } 38 //更新 39 }*root, *nil, _nil, mem[MAXN]; 40 int tot; 41 42 void pushdown(Node *&t){ 43 if (t == nil) return; 44 if (t->turn){ 45 Node *p; 46 p = t->ch[0]; 47 t->ch[0] = t->ch[1]; 48 t->ch[1] = p; 49 50 if (t->ch[0] != nil) t->ch[0]->turn ^= 1; 51 if (t->ch[1] != nil) t->ch[1]->turn ^= 1; 52 t->turn = 0; 53 } 54 } 55 void update(Node *&t){ 56 t->size = 1; 57 t->size += t->ch[0]->size + t->ch[1]->size; 58 } 59 Node* NEW(int val){ 60 Node *p = &mem[tot++]; 61 p->val = val; 62 p->size = 1; 63 p->turn = 0; 64 p->parent = p->ch[0] = p->ch[1] = nil; 65 return p; 66 } 67 void init(){ 68 //哨兵初始化 69 nil = &_nil; 70 _nil.val = _nil.size = _nil.turn = 0; 71 _nil.parent = _nil.ch[0] = _nil.ch[1] = nil; 72 73 tot = 0; 74 root = NEW(INF); 75 root->ch[1] = NEW(INF); 76 root->ch[1]->parent = root; 77 } 78 //1为右旋 79 /*void Rotate(Node *&t, int d){ 80 Node *p = t->parent; 81 pushdown(p); 82 pushdown(t); 83 pushdown(t->ch[d]); 84 //t = p->ch[d ^ 1];这句话是废话,真正的一句一处 85 p->ch[d ^ 1] = t->ch[d]; 86 if (t->ch[d] != nil) t->ch[d]->parent = p; 87 t->parent = p->parent; 88 if (p->parent != nil) p->ch[p->cmp()] = t; 89 t->ch[d] = p; 90 p->parent = t; 91 update(p);//注意这里为什么只要updatep是因为旋转是在伸展中使用的,因此t的更新在splay中 92 if (root == p) root = t;//换根 93 }*/ 94 void Rotate(Node *t, int d){ 95 Node *p = t->parent;//t的右旋对于p来说也是右旋 96 t = p->ch[d ^ 1]; 97 p->ch[d ^ 1] = t->ch[d]; 98 t->ch[d]->parent = p; 99 t->ch[d] = p; 100 t->parent = p->parent; 101 //注意,这里要更新的原因在于t并不是引用 102 if (t->parent != nil){ 103 if (t->parent->ch[0] == p) t->parent->ch[0] = t; 104 else if (t->parent->ch[1] == p) t->parent->ch[1] = t; 105 } 106 p->parent = t; 107 if (t->parent == nil) root = t; 108 //不用换回去了... 109 update(p); 110 update(t); 111 //t->update(); 112 } 113 void splay(Node *x, Node *y){ 114 pushdown(x); 115 while (x->parent != y){ 116 if (x->parent->parent == y){ 117 Rotate(x, x->cmp() ^ 1); 118 break; 119 }else{ 120 Rotate(x->parent, x->parent->cmp() ^ 1); 121 Rotate(x, x->cmp() ^ 1); 122 } 123 update(x); 124 } 125 update(x);//最后退出的update不要忘了 126 if (nil == y) root = x; 127 } 128 //找到第k小的数并将其伸展到y 129 void find(Node *y, int k){ 130 Node *x = root; 131 while (1){ 132 //if (x == nil) break;//注意我已经在init中插入了两个数 133 pushdown(x); 134 int tmp = (x->ch[0]->size); 135 if ((tmp + 1) == k) break; 136 if (k <= tmp) x = x->ch[0]; 137 else k -= tmp + 1, x = x->ch[1]; 138 } 139 pushdown(x); 140 splay(x, y); 141 } 142 //在pos位置后面插入一个数val 143 void Insert(int pos, int val){ 144 find(nil, pos + 1); 145 find(root, pos + 2);//时刻注意已经插入了两个INF 146 pushdown(root); 147 pushdown(root->ch[1]); 148 Node *p = NEW(val), *t = root->ch[1]; 149 //一定要拆开!!不能放在ch[1]->[0] 150 p->ch[1] = t; 151 t->parent = p; 152 root->ch[1] = p; 153 p->parent = root; 154 splay(p, nil); 155 } 156 //剪掉a,b位置的数并接到c位置后面 157 void Cut(int a, int b, int c){ 158 find(nil, a); 159 find(root, b + 2); 160 pushdown(root); 161 pushdown(root->ch[1]); 162 163 Node *p = root->ch[1]->ch[0]; 164 root->ch[1]->ch[0] = nil;//剪掉 165 update(root->ch[1]);///不要忘了更新 166 update(root); 167 168 find(nil, c + 1); 169 find(root, c + 2); 170 pushdown(root); 171 pushdown(root->ch[1]); 172 173 root->ch[1]->ch[0] = p; 174 p->parent = root->ch[1]; 175 update(root->ch[1]); 176 update(root); 177 splay(p, nil); 178 } 179 void Reverse(int l, int r){ 180 find(nil, l); 181 find(root, r + 2); 182 //print(root); 183 root->ch[1]->ch[0]->turn ^= 1; 184 Node *p = root->ch[1]->ch[0]; 185 splay(p, nil); 186 } 187 void print(Node *t){ 188 if (t == nil) return; 189 pushdown(t); 190 print(t->ch[0]); 191 if (t->val != INF){ 192 if (M != 1) {printf("%d ", t->val);M--;} 193 else printf("%d", t->val); 194 } 195 print(t->ch[1]); 196 } 197 }A; 198 int n, m; 199 200 void init(){ 201 A.init(); 202 //scanf("%d%d", &n, &m); 203 for (int i = 0; i < n; i++){ 204 A.Insert(i, i + 1); 205 } 206 //A.print(A.root); 207 } 208 void work(){ 209 for (int i = 1; i <= m; i++){ 210 char str[10]; 211 scanf("%s", str); 212 if (str[0] == ‘C‘){ 213 int a, b, c; 214 scanf("%d%d%d", &a, &b, &c); 215 A.Cut(a, b, c); 216 }else{ 217 int l, r; 218 scanf("%d%d", &l, &r); 219 A.Reverse(l, r); 220 } 221 //A.print(A.root); 222 } 223 M = n; 224 A.print(A.root); 225 } 226 227 int main(){ 228 229 while (scanf("%d%d", &n, &m)){ 230 if (n == -1 && m == -1) break; 231 init(); 232 //A.find(A.nil, 3); 233 //printf("%d", A.root->size); 234 work(); 235 printf("\n"); 236 } 237 return 0; 238 }
【HDU3487】【splay分裂合并】Play with Chain
标签:
原文地址:http://www.cnblogs.com/hoskey/p/4331616.html