Skip to Content
Team NoteAlgorithmSplayTree-Array

SplayTree-Array

struct node { node *l = 0, *r = 0, *p = 0; int val, sum, cnt = 1, lazy = 0, flip = 0, mx, mn, dummy = 0; node(int val) : val(val), sum(val), mx(val), mn(val) {} }; struct splay_tree { const int inf = numeric_limits<int>::max() >> 1; node *root = 0; vector<node *> ptr; void init(const vector<int> &arr) { // 0-based int n = sz(arr); ptr.resize(n + 1); node *x = root = new node(-inf); for (int i = 1; i <= n; i++) ptr[i] = x = add_r(x, arr[i - 1]); x->r = add_r(x, inf); root->dummy = x->r->dummy = 1; for (int i = n; i >= 1; i--) update(ptr[i]); splay(ptr[(n + 1) / 2]); } void init(int n, int s = 0) { vi a(n); iota(all(a), s); init(a); } void shift(int l, int r, int s) { // 1-based, to right s = md(r - l + 1, s); if (!s) return; flip(l, r), flip(l, l + s - 1), flip(l + s, r); } void flip(int nl, int nr) { // 1-based node *x = gather(nl, nr); x->flip ^= 1; } void propagate(node *x) { if (x->flip) swap(x->l, x->r); x->val += x->lazy; if (x->l) { if (x->flip) x->l->flip ^= 1; x->l->lazy += x->lazy; x->l->sum += x->l->cnt * x->lazy; x->l->mn += x->lazy; x->l->mx += x->lazy; } if (x->r) { if (x->flip) x->r->flip ^= 1; x->r->lazy += x->lazy; x->r->sum += x->r->cnt * x->lazy; x->r->mn += x->lazy; x->r->mx += x->lazy; } x->lazy = x->flip = 0; } node *gather(int nl, int nr) { kth(nr + 1); node *tmp = root; kth(nl - 1); splay(tmp, root); return root->r->l; } int kth(int k) { // 1-based node *x = root; propagate(x); while (1) { while (x->l && x->l->cnt > k) x = x->l, propagate(x); if (x->l)k -= x->l->cnt; if (!k--)break; x = x->r, propagate(x); } splay(x); return root->val; } void splay(node *x, node *g = 0) { while (x->p != g) { node *p = x->p; if (p->p == g) { rotate(x); break; } node *pp = p->p; if ((x == p->l) == (p == pp->l))rotate(p), rotate(x); else rotate(x), rotate(x); } if (!g) root = x; } void rotate(node *x) { node *p = x->p, *c; if (!p) return; propagate(p), propagate(x); if (x == p->l) { p->l = c = x->r; x->r = p; } else { p->r = c = x->l; x->l = p; } x->p = p->p; p->p = x; if (c) c->p = p; if (!x->p)root = x; else if (p == x->p->l) x->p->l = x; else x->p->r = x; update(p), update(x); } void update(node *x) { x->cnt = 1; x->sum = x->mn = x->mx = x->val; if (x->l) { x->cnt += x->l->cnt; x->sum += x->l->sum; x->mn = min(x->mn, x->l->mn); x->mx = max(x->mx, x->l->mx); } if (x->r) { x->cnt += x->r->cnt; x->sum += x->r->sum; x->mn = min(x->mn, x->r->mn); x->mx = max(x->mx, x->r->mx); } } node *add_l(node *x, int val) { node *c = new node(val); c->p = x; return x->l = c; } node *add_r(node *x, int val) { node *c = new node(val); c->p = x; return x->r = c; } void inorder(node *x) { propagate(x); if (x->l)inorder(x->l); if (!x->dummy) cout << x->val << ' '; if (x->r)inorder(x->r); } };
Last updated on