原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1269
伸展树的运用,如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using std::swap; 7 const int Max_N = 3000010; 8 struct Node{ 9 char chr; 10 int s; 11 bool rev; 12 Node *pre, *ch[2]; 13 inline void 14 set(char _chr = ' ', int _s = 0, Node *p = NULL){ 15 chr = _chr, s = _s, rev = 0; 16 pre = ch[0] = ch[1] = p; 17 } 18 inline void push_up(){ 19 s = ch[0]->s + ch[1]->s + 1; 20 } 21 inline void update(){ 22 rev ^= 1; 23 swap(ch[0], ch[1]); 24 } 25 inline void push_down(){ 26 if (rev != 0){ 27 rev ^= 1; 28 ch[0]->update(); 29 ch[1]->update(); 30 } 31 } 32 }; 33 struct SplayTree{ 34 char buf[Max_N]; 35 Node *tail, *root, *null; 36 Node stack[Max_N], *store[Max_N]; 37 int top, pos; 38 void init(){ 39 top = 0, pos = 0; 40 tail = &stack[0]; 41 null = tail++; 42 null->set(); 43 root = newNode(' '); 44 root->ch[1] = newNode(' '); 45 root->ch[1]->pre = root; 46 root->ch[1]->push_up(); 47 root->push_up(); 48 } 49 inline Node *newNode(char chr){ 50 Node *p = null; 51 if (!top) p = tail++; 52 else p = store[--top]; 53 p->set(chr, 1, null); 54 return p; 55 } 56 inline void rotate(Node *x, int c){ 57 Node *y = x->pre; 58 y->push_down(), x->push_down(); 59 y->ch[!c] = x->ch[c]; 60 x->pre = y->pre; 61 if (x->ch[c] != null) x->ch[c]->pre = y; 62 if (y->pre != null) y->pre->ch[y->pre->ch[0] != y] = x; 63 x->ch[c] = y; 64 y->pre = x; 65 y->push_up(); 66 if (y == root) root = x; 67 } 68 inline void splay(Node *x, Node *f){ 69 if (x == root) return; 70 for (; x->pre != f; x->push_down()){ 71 if (x->pre->pre == f){ 72 rotate(x, x->pre->ch[0] == x); 73 } else { 74 Node *y = x->pre, *z = y->pre; 75 if (z->ch[0] == y){ 76 if (y->ch[0] == x) 77 rotate(y, 1), rotate(x, 1); 78 else rotate(x, 0), rotate(x, 1); 79 } else { 80 if (y->ch[1] == x) 81 rotate(y, 0), rotate(x, 0); 82 else rotate(x, 1), rotate(x, 0); 83 } 84 } 85 } 86 x->push_up(); 87 } 88 inline Node *built(int l, int r){ 89 if (l > r) return null; 90 int mid = (l + r) >> 1; 91 Node *p = newNode(buf[mid]); 92 p->ch[0] = built(l, mid - 1); 93 if (p->ch[0] != null) p->ch[0]->pre = p; 94 p->ch[1] = built(mid + 1, r); 95 if (p->ch[1] != null) p->ch[1]->pre = p; 96 p->push_up(); 97 return p; 98 } 99 inline void recycle(Node *x){ 100 if (x != null){ 101 recycle(x->ch[0]); 102 store[top++] = x; 103 recycle(x->ch[1]); 104 } 105 } 106 inline Node *select(Node *x, int k){ 107 for (int t = 0; x != null;){ 108 x->push_down(); 109 t = x->ch[0]->s; 110 if (k == t + 1) break; 111 else if (k <= t) x = x->ch[0]; 112 else k -= t + 1, x = x->ch[1]; 113 } 114 return x; 115 } 116 inline void get_range(int x, int y){ 117 splay(select(root, x + 1), null); 118 splay(select(root, y + 2), root); 119 } 120 inline void Gets(char *s){ 121 char c; 122 while (c = getchar(), c != '\n') *s++ = c; 123 *s = '\0'; 124 } 125 inline void insert(int n){ 126 char c; 127 scanf("%c", &c); 128 Gets(buf + 1); 129 get_range(pos, pos); 130 Node *ret = built(1, n); 131 root->ch[1]->ch[0] = ret; 132 ret->pre = root->ch[1]; 133 root->ch[1]->push_up(); 134 root->push_up(); 135 } 136 inline void del(int n){ 137 get_range(pos, pos + n); 138 Node* &ret = root->ch[1]; 139 ret->ch[0]->pre = null; 140 #ifdef LOCAL 141 recycle(ret->ch[0]); 142 #endif 143 ret->ch[0] = null; 144 ret->push_up(); 145 root->push_up(); 146 } 147 inline void rotate(int n){ 148 get_range(pos, pos + n); 149 root->ch[1]->ch[0]->update(); 150 } 151 inline void get(){ 152 splay(select(root, pos + 2), null); 153 printf("%c\n", root->chr); 154 } 155 inline void move(){ 156 scanf("%d", &pos); 157 } 158 inline void prev(){ 159 pos--; 160 } 161 inline void next(){ 162 pos++; 163 } 164 }spt; 165 int main(){ 166 #ifdef LOCAL 167 freopen("in.txt", "r", stdin); 168 freopen("out.txt", "w+", stdout); 169 #endif 170 spt.init(); 171 int m, n; 172 char str[100]; 173 scanf("%d", &m); 174 while (m--){ 175 scanf("%s", str); 176 switch (str[0]){ 177 case 'M': 178 spt.move(); 179 break; 180 case 'I': 181 scanf("%d", &n); 182 spt.insert(n); 183 break; 184 case 'D': 185 scanf("%d", &n); 186 spt.del(n); 187 break; 188 case 'N': 189 spt.next(); 190 break; 191 case 'P': 192 spt.prev(); 193 break; 194 case 'R': 195 scanf("%d", &n); 196 spt.rotate(n); 197 break; 198 case 'G': 199 spt.get(); 200 break; 201 } 202 } 203 return 0; 204 }