SYSU-6, Gym 100125L, splay

题目大意:每次往一个串里某个位置连续插n个字符a,或者删除一个区间,或者询问区间内有多少个字母(字母类型一共不超过26个),或者删除一段区间。

解:splay经典题,比较蛋疼的是删除,等价于把连续一段分裂成3(可以两个节点),我的写法很蠢,之后看了一下别人的代码如果维护一个找这个端点的上一个和下一个端点的函数能大幅减少创建节点的数量,这样写会快些,但是我手里积了很多其他题,也没时间改良了,日后有时间重写练手的时候改一下写法吧。

 

  1 #include <cstdio>
  2 #include <string>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <cstring>
  7 #include <complex>
  8 #include <set>
  9 #include <vector>
 10 #include <map>
 11 #include <queue>
 12 #include <deque>
 13 #include <ctime>
 14 
 15 using namespace std;
 16 
 17 const double EPS = 1e-8;
 18 
 19 #define ABS(x) ((x)<0?(-(x)):(x))
 20 #define SQR(x) ((x)*(x))
 21 #define MIN(a,b) ((a)<(b)?(a):(b))
 22 #define MAX(a,b) ((a)>(b)?(a):(b))
 23 
 24 #define LSON(x) ((x)<<1)
 25 #define RSON(x) (((x)<<1)+1)
 26 #define LOWBIT(x) ((x)&(-(x)))
 27 #define MAXN 611111
 28 #define VOIDPOINT 0
 29 #define LL long long
 30 #define OO 214748364
 31 
 32 struct node{
 33     node *ch[2], *fath;
 34     int size, tag, w, l;
 35     inline int count() {
 36         int res = 0;
 37         for (int i = tag; i; i -= LOWBIT(i)) ++res;
 38         return res;
 39     }
 40     inline void updata() {
 41         size = l + (ch[0] ? ch[0]->size : 0) + (ch[1] ? ch[1]->size : 0);
 42         tag = (ch[0] ? ch[0]->tag : 0) | (ch[1] ? ch[1]->tag : 0) | (1 << w);
 43     }
 44     inline void setCh(node *lson = VOIDPOINT, node *rson = VOIDPOINT) {
 45         ch[0] = lson; if (lson) lson->fath = this;
 46         ch[1] = rson; if (rson) rson->fath = this;
 47     }
 48 };
 49 
 50 struct SplayTree{
 51     node tree[MAXN], *root;
 52     int cnt;
 53     void clear() {
 54         cnt = 0;
 55         memset(tree, 0, sizeof(tree[0]));
 56     }
 57     node* newNode(int _w = 0, int _l = 0, node *father = VOIDPOINT) {
 58         node *u = &tree[++cnt];
 59 
 60         u->ch[0] = u->ch[1] = VOIDPOINT;
 61         u->w = _w; u->l = _l;
 62         u->size = _l; u->tag = (1 << _w);
 63         u->fath = father;
 64 
 65         return u;
 66     }
 67     inline void rotate(node *now) {
 68         node *p, *q;
 69         p = now->fath; q = p->fath;
 70         now->fath = q; p->fath = now;
 71         if (p->ch[0] == now) {
 72             if (p->ch[0] = now->ch[1]) p->ch[0]->fath = p;
 73             now->ch[1] = p;
 74         } else {
 75             if (p->ch[1] = now->ch[0]) p->ch[1]->fath = p;
 76             now->ch[0] = p;
 77         }
 78         if (q) {
 79             if (q->ch[0] == p) q->ch[0] = now;
 80             else q->ch[1] = now;
 81         }
 82         p->updata();
 83     }
 84     inline void splay(node *now, node *goal = VOIDPOINT) {
 85         node *p, *q;
 86         while (now->fath != goal) {
 87             p = now->fath; q = p->fath;
 88             if (q == goal) {
 89                 rotate(now); break;
 90             }
 91             if ((now == p->ch[0] && p == q->ch[0]) || (now == p->ch[1] && p == q->ch[1])) {
 92                 rotate(p); rotate(now);
 93             } else {
 94                 rotate(now); rotate(now);
 95             }
 96         }
 97         now->updata();
 98         if (goal == VOIDPOINT) root = now;
 99     }
100     node* insert(int pos, int val, int len) {
101         if (cnt == 0) {
102             root = newNode(val, len, VOIDPOINT); return root;
103         }
104         node *u = root;
105         for (;;) {
106             int tmp = (u->ch[0] ? u->ch[0]->size : 0);
107             if (pos <= tmp) {
108                 if (u->ch[0] == VOIDPOINT) { 
109                     u->ch[0] = newNode(val, len, u); 
110                     splay(u->ch[0]); break;
111                 }
112                 u = u->ch[0];
113             } else if (pos > tmp + u->l ) {
114                 if (u->ch[1] == VOIDPOINT) {
115                     u->ch[1] = newNode(val, len, u); 
116                     splay(u->ch[1]); break;
117                 }
118                 pos -= tmp + u->l; u = u->ch[1];
119             } else {
120                 pos -= tmp;
121                 int lsz = pos - 1, rsz = u->l - pos + 1;
122                 node *p, *q, *tt;
123                 tt = newNode(val, len, u->fath); 
124                 
125                 if (u->fath)
126                     u->fath->ch[ u->fath->ch[1] == u ] = tt;
127 
128                 p = lsz == 0 ? u->ch[0] : newNode(u->w, lsz, tt); 
129 
130                 q = newNode(u->w, rsz, tt); q->setCh(VOIDPOINT, u->ch[1]); q->updata();
131 
132                 if (lsz == 0) {
133                     tt->setCh(u->ch[0], q);
134                 } else {
135                     p->setCh(u->ch[0], VOIDPOINT); p->updata();
136                     tt->setCh(p, q);
137                 }
138                 splay(tt);
139                 break;
140             }
141         }
142     }
143     node* find(int pos) {
144         node *u = root;
145         for (;;) {
146             int tmp = u->ch[0] ? u->ch[0]->size : 0;
147             if (pos <= tmp) u = u->ch[0];
148             else if (pos > tmp + u->l) {
149                 pos -= tmp + u->l;
150                 u = u->ch[1];
151             }
152             else break;
153         }
154         return u;
155     }
156     void deletee(int l, int r) {
157         insert(l, 26, 1); insert(r+2, 26, 1);
158         node *t = find(r+3), *t2 = find(l-1);
159         splay(t2);
160         splay(find(r+3), t2);
161         t->ch[0] = VOIDPOINT; t->updata(); t->fath->updata();
162     }
163     int query(int l, int r) {
164         insert(l, 26, 1); insert(r+2, 26, 1);
165 
166         node *t = find(l), *t2 = find(r+2);
167         splay(t);
168         splay(t2, t);
169 
170         int res = t2->ch[0]->count();
171 
172         deletee(r+2, r+2); deletee(l, l);
173         return res;
174     }
175 
176     void dfs(node *u) const {
177         if (u->ch[0]) dfs(u->ch[0]);
178         
179         for (int i = 0; i < u->l; ++i) putchar(u->w+'a');
180         if (u->ch[1]) dfs(u->ch[1]);
181     }
182     void show() const {
183         node *u = root;
184         dfs(root);
185         cout << endl << "show end =========================== "<< root->size << endl;
186     }
187 } Tree;
188 
189 int main() {
190     freopen("test.txt", "r", stdin);
191 //    freopen("log.in", "r", stdin);
192 //    freopen("log.out", "w", stdout);
193 
194     Tree.clear();
195     Tree.insert(1, 26, 1); 
196     Tree.insert(1+1, 26, 1);
197     int n, pos, len, val; scanf("%d", &n);
198     char s[11];
199     while (n--) {
200 //        Tree.show();
201         scanf("%s", s);
202         if (s[0] == '+') {
203             scanf("%d%d%s", &pos, &len, s); val = s[0] - 'a';
204             Tree.insert(pos+1, val, len);
205         } else if (s[0] == '-') {
206             scanf("%d%d", &pos, &len);
207             Tree.deletee(pos+1, pos+1+len-1);
208         } else if (s[0] == '?') {
209             scanf("%d%d", &pos, &len); 
210             printf("%d\n", Tree.query(pos+1, len+1));
211         } else puts("Err");
212     }
213 //    Tree.show();
214     fclose(stdin);
215     fclose(stdout);
216     return 0;
217 }
Gym 100125L

 

posted @ 2016-07-07 09:59  F.D.His.D  阅读(305)  评论(0编辑  收藏  举报