标签:
Splay的区间维护还是很机智的,不好写是真的。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define REP(i, s, n) for(int i = s; i <= n; i ++) 7 #define RAP(i, n, s) for(int i = n; i >= s; i --) 8 using namespace std; 9 const int maxn = 100000 + 10; 10 char S[maxn]; int Q; 11 inline void read(int &x){ 12 x = 0; int sig = 1; char ch = getchar(); 13 while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); } 14 while(isdigit(ch)) x = 10 * x + ch - ‘0‘, ch = getchar(); 15 x *= sig; return ; 16 } 17 inline void write(int x){ 18 if(x < 0) putchar(‘-‘), x = -x; 19 int len = 0, buf[20]; 20 while(x) buf[++ len] = x % 10, x /= 10; 21 RAP(i, len, 0) putchar(buf[i] + ‘0‘); return ; 22 } 23 struct Node{ 24 int s, flip; char c; 25 Node* ch[2]; 26 int cmp(int k){ 27 return k == ch[0] -> s + 1 ? -1 : k > ch[0] -> s; 28 } 29 void maintain(){ 30 s = ch[0] -> s + ch[1] -> s + 1; return ; 31 } 32 void pushdown(){ 33 if(flip) ch[0] -> flip ^= 1, ch[1] -> flip ^= 1, swap(ch[0], ch[1]), flip = 0; return ; 34 } 35 }* null = new Node(), nodes[maxn], * root, * _o, * _left, * _right, * _mid; 36 int ms = 0; 37 void rotate(Node* &o, int d){ 38 Node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o; 39 o -> maintain(); k -> maintain(); o = k; return ; 40 } 41 void splay(Node* &o, int k1){ 42 o -> pushdown(); int d1 = o -> cmp(k1); 43 if(d1) k1 -= o -> ch[0] -> s + 1; if(d1 == -1) return ; 44 Node* p = o -> ch[d1]; p -> pushdown(); 45 int d2 = p -> cmp(k1), k2 = d2 ? k1 - p -> ch[0] -> s - 1 : k1; 46 if(d2 != -1){ 47 splay(p -> ch[d2], k2); 48 if(d1 == d2) rotate(o, d1 ^ 1); else rotate(o -> ch[d1], d1); 49 } 50 rotate(o, d1 ^ 1); return ; 51 } 52 void print(Node* &o){ 53 if(o == null) return ; 54 o -> pushdown(); 55 print(o -> ch[0]); 56 putchar(o -> c); 57 print(o -> ch[1]); 58 return ; 59 } 60 void build(Node* &o, int L, int R){ 61 o = null; if(L > R) return ; 62 int M = L + R >> 1; o = &nodes[ms ++]; 63 o -> c = S[M]; o -> flip = 0; 64 build(o -> ch[0], L, M - 1); build(o -> ch[1], M + 1, R); //不包含M的两块 65 o -> maintain(); return ; 66 } 67 void merge(Node* &left, Node* &right){ 68 if(left == null) left = right; 69 else splay(left, left -> s), left -> ch[1] = right, left -> maintain();//截掉右子树粘过去,别忘了重新维护一下 70 return ; 71 } 72 void split(Node* &o, Node* &left, Node* &right, int k){//前k小扔到left里 73 if(k <= 0) left = null, right = o;//直接搞好了o(* ̄3 ̄)o 74 else splay(o, k), left = o, right = left -> ch[1], left -> ch[1] = null, left -> maintain();//砍掉左子树的右孩子贴到右边去,别忘了维护值 75 return ; 76 } 77 void init(){ 78 scanf("%s", S); read(Q); 79 build(root, 0, strlen(S) - 1); 80 return ; 81 } 82 void work(){ 83 int L, R; 84 while(Q --){ 85 read(L); read(R); 86 split(root, _left, _o, L - 1); split(_o, _mid, _right, R - L + 1);//先拆root再拆 o (⊙ ▽ ⊙) 87 _mid -> flip ^= 1; 88 merge(_left, _mid); merge(_left, _right); root = _left;//哦哦一点点合并,merge又不是三元的 (⊙ ▽ ⊙),别忘了root要更新回来 89 } 90 return ; 91 } 92 void print(){ 93 print(root); 94 return ; 95 } 96 int main(){ 97 init(); 98 work(); 99 print(); 100 return 0; 101 }
标签:
原文地址:http://www.cnblogs.com/chxer/p/4426226.html