Splay模板

Splay(Tyvj 1728/Bzoj 3224 普通平衡树)

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 struct node {
  6     int data, size, cnt;
  7     node *child[2], *father;
  8 
  9     void pushup() {
 10         size = child[0]->size + child[1]->size + cnt;
 11     }
 12 
 13     node() {
 14         data = size = cnt = 0;
 15         child[0] = child[1] = father = NULL;
 16     }
 17 
 18 } *root = new node, *nul = new node;
 19 
 20 node* newnode(int data, node *fa) {
 21     node *cur = new node;
 22     cur->data = data, cur->size = cur->cnt = 1;
 23     cur->child[0] = cur->child[1] = nul; cur->father = fa;
 24     return cur;
 25 }
 26 
 27 bool getp(node *cur) {
 28     return (cur->father->child[1] == cur);
 29 }
 30 
 31 void connect(node *x, node *y, int p) {
 32     x->father = y;
 33     y->child[p] = x;
 34 }
 35 
 36 void rotate(node *cur) {
 37     int p = getp(cur), p2 = getp(cur->father);
 38     node *r = cur->father->father;
 39     connect(cur->child[p ^ 1], cur->father, p);
 40     connect(cur->father, cur, p ^ 1);
 41     connect(cur, r, p2);
 42     cur->child[p ^ 1]->pushup(); cur->pushup();
 43 }
 44 
 45 void splay(node *cur, node *to) {
 46     while(cur->father != to) {
 47         node *fa = cur->father, *gfa = cur->father->father;
 48         if(gfa != to) {
 49             if(getp(cur) == getp(fa)) rotate(fa);
 50             else rotate(cur);
 51         }
 52         rotate(cur);
 53     }
 54 }
 55 
 56 node *find(node *cur, int v) {
 57     if(cur == nul)
 58         return nul;
 59     if(cur->data == v) {
 60         splay(cur, root);
 61         return cur;
 62     } else return find(cur->child[v > cur->data], v);
 63 }
 64 
 65 void insert(node *&cur, node *fa, int v) {
 66     if(cur == nul) {
 67         cur = newnode(v, fa);
 68         splay(cur, root);
 69     } else if(cur->data == v) {
 70         cur->cnt++;
 71         splay(cur, root);
 72     } else insert(cur->child[v > cur->data], cur, v);
 73     cur->pushup();
 74 }
 75 
 76 int rnk(node *cur, int v) {
 77     if(cur == nul) return 1;
 78     if(cur->data > v) return rnk(cur->child[0], v);
 79     else if(cur->data < v)
 80         return cur->child[0]->size + cur->cnt + rnk(cur->child[1], v);
 81     else {
 82         int ans = cur->child[0]->size + 1;
 83         splay(cur, root);
 84         return ans;
 85     }
 86 }
 87 
 88 int findkth(node *cur, int k) {
 89     if(k <= cur->child[0]->size) return findkth(cur->child[0], k);
 90     else if(k > cur->child[0]->size + cur->cnt)
 91         return findkth(cur->child[1], k - cur->child[0]->size - cur->cnt);
 92     else {
 93         splay(cur, root);
 94         return cur->data;
 95     }
 96 }
 97 
 98 void del(int v) {
 99     node *cur = find(root->child[1], v), *lcbt = cur->child[0];
100     if(cur->cnt > 1) {
101         cur->cnt--;
102         return;
103     }
104     while(lcbt->child[1] != nul) lcbt = lcbt->child[1];
105     if(lcbt != nul) {
106         splay(lcbt, cur);
107         connect(lcbt, root, 1);
108         connect(cur->child[1], lcbt, 1);
109         lcbt->pushup();
110     } else connect(cur->child[1], root, 1);
111     delete cur;
112 }
113 
114 int main() {
115     ios::sync_with_stdio(false);
116     int n, opt, x;
117     cin >> n;
118     nul->father = nul->child[0] = nul->child[1] = nul;
119     root->father = root->child[0] = root->child[1] = nul;
120     root->data = 0x7fffffff;
121     while(n--) {
122         cin >> opt >> x;
123         if(opt == 1) insert(root->child[1], root, x);
124         if(opt == 2) del(x);
125         if(opt == 3) cout << rnk(root->child[1], x) << endl;
126         if(opt == 4) cout << findkth(root->child[1], x) << endl;
127         if(opt == 5) cout << findkth(root->child[1], rnk(root->child[1], x) - 1) << endl;
128         if(opt == 6) cout << findkth(root->child[1], rnk(root->child[1], x + 1)) << endl;
129     }
130     return 0;
131 }
View Code

Splay区间翻转 (Tyvj 1729/Bzoj3223 文艺平衡树)

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 int n, m;
  6 
  7 struct node {
  8 
  9     int val, size, tag;
 10     node *child[2], *father;
 11 
 12     node() {
 13         val = size = tag = 0;
 14     }
 15 
 16     void pushup() {
 17         size = child[0]->size + child[1]->size + 1;
 18     }
 19 
 20     void pushtag() {
 21         if(tag) {
 22             child[0]->tag ^= 1;
 23             child[1]->tag ^= 1;
 24             swap(child[0], child[1]);
 25             tag = 0;
 26         }
 27     }
 28 
 29     int wson() {
 30         return this == father->child[1];
 31     }
 32 
 33 } *root = new node, *nul = new node;
 34 
 35 void init() {
 36     nul->child[0] = nul->child[1] = nul->father = nul;
 37     root->child[0] = root->child[1] = root->father = nul;
 38 }
 39 
 40 void connect(node *x, node *y, int p) {
 41     x->father = y; y->child[p] = x;
 42 }
 43 
 44 node *newnode(int v, node *fa) {
 45     node *cur = new node;
 46     cur->val = v; cur->size = 1;
 47     cur->child[0] = cur->child[1] = nul;
 48     cur->father = fa;
 49     return cur;
 50 }
 51 
 52 void rotate(node *&cur) {
 53     int p = cur->wson(), fp = cur->father->wson();
 54     node *rt = cur->father->father;
 55     connect(cur->child[p ^ 1], cur->father, p);
 56     connect(cur->father, cur, p ^ 1);
 57     connect(cur, rt, fp);
 58     cur->child[p ^ 1]->pushup(); cur->pushup();
 59 }
 60 
 61 void splay(node *cur, node *goal) {
 62     while(cur->father != goal) {
 63         node *fa = cur->father, *gfa = cur->father->father;
 64         if(gfa != goal) {
 65             if(cur->wson() == fa->wson()) rotate(fa);
 66             else rotate(cur);
 67         }
 68         rotate(cur);
 69     }
 70 }
 71 
 72 void build(node *&cur, node *fa, int l, int r) {
 73     if(l <= r) {
 74         int mid = (l + r) >> 1;
 75         cur = newnode(mid, fa);
 76         build(cur->child[0], cur, l, mid - 1);
 77         build(cur->child[1], cur, mid + 1, r);
 78         cur->pushup();
 79     }
 80 }
 81 
 82 node* findkth(node *cur, int k) {
 83     cur->pushtag();
 84     if(k <= cur->child[0]->size) return findkth(cur->child[0], k);
 85     else if(k > cur->child[0]->size + 1)
 86         return findkth(cur->child[1], k - cur->child[0]->size - 1);
 87     else return cur;
 88 }
 89 
 90 void reverse(int l, int r) 
 91 {
 92     splay(findkth(root->child[1], l - 1), root);
 93     splay(findkth(root->child[1], r + 1), root->child[1]);
 94     root->child[1]->child[1]->child[0]->tag ^= 1;
 95 }
 96 
 97 void ldr(node *cur) {
 98     if(cur == nul) return;
 99     cur->pushtag();
100     ldr(cur->child[0]);
101     if(cur->val != 1 && cur->val != n + 2) cout << cur->val - 1 << " ";
102     ldr(cur->child[1]);
103 }
104 
105 int main() {
106     init();
107     int x, y;
108     cin >> n >> m;
109     build(root->child[1], root, 1, n + 2);
110     while(m--) {
111         cin >> x >> y;
112         reverse(x + 1, y + 1);
113     }
114     ldr(root->child[1]);
115     cout << endl;
116     return 0;
117 }
View Code

 

posted @ 2018-08-22 06:48  zhylj  阅读(202)  评论(0编辑  收藏  举报