bzoj 1269 [AHOI2006]文本编辑器editor

原题链接: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 }
View Code

 

你可能感兴趣的:(editor)