diff --git a/README.md b/README.md index 52372ea..f677ce7 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,12 @@ curl -L "https://raw.githubusercontent.com/theSoberSobber/CP-Snippets/main/snipp - **[rr-segtree](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2190)** : best segtree - **[segtree](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2334)** : sextree - **[seive](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2448)** : seive -- **[tokenizer](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2466)** : tokenizer that has no use -- **[totient-seive](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2473)** : totient-seive -- **[totient](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2487)** : totient -- **[trie](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2507)** : trie -- **[troll](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2543)** : troll -- **[two-sat (kosaraju)](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2553)** : two-sat (kosaraju) -- **[variadic](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2690)** : variadic lambdas with 1 and 2 arguments -- **[xor-basis](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2699)** : xor-basis \ No newline at end of file +- **[splay-tree-rr-sir](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2466)** : used here by rr sir, I have no idea how to use it or what it's used in mostly, [RR Sir ABC F Submission](https://atcoder.jp/contests/abc350/submissions/52600529) +- **[tokenizer](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2661)** : tokenizer that has no use +- **[totient-seive](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2668)** : totient-seive +- **[totient](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2682)** : totient +- **[trie](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2702)** : trie +- **[troll](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2738)** : troll +- **[two-sat (kosaraju)](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2748)** : two-sat (kosaraju) +- **[variadic](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2885)** : variadic lambdas with 1 and 2 arguments +- **[xor-basis](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2894)** : xor-basis \ No newline at end of file diff --git a/book/codebook-dark.pdf b/book/codebook-dark.pdf index fd2a1f8..b6e4cad 100644 Binary files a/book/codebook-dark.pdf and b/book/codebook-dark.pdf differ diff --git a/book/codebook-light.pdf b/book/codebook-light.pdf index 16970b9..1b064c6 100644 Binary files a/book/codebook-light.pdf and b/book/codebook-light.pdf differ diff --git a/docs/README.md b/docs/README.md index 8d2d9cb..259b293 100644 --- a/docs/README.md +++ b/docs/README.md @@ -78,6 +78,7 @@ curl -L "https://raw.githubusercontent.com/theSoberSobber/CP-Snippets/main/snipp - **[rr-segtree](https://thesobersobber.github.io/CP-Snippets/rr-segtree)** : best segtree - **[segtree](https://thesobersobber.github.io/CP-Snippets/segtree)** : sextree - **[seive](https://thesobersobber.github.io/CP-Snippets/seive)** : seive +- **[splay-tree-rr-sir](https://thesobersobber.github.io/CP-Snippets/Splay Tree)** : used here by rr sir, I have no idea how to use it or what it's used in mostly, [RR Sir ABC F Submission](https://atcoder.jp/contests/abc350/submissions/52600529) - **[tokenizer](https://thesobersobber.github.io/CP-Snippets/tokenizer)** : tokenizer that has no use - **[totient-seive](https://thesobersobber.github.io/CP-Snippets/totient-seive)** : totient-seive - **[totient](https://thesobersobber.github.io/CP-Snippets/totient)** : totient diff --git a/docs/Splay Tree.md b/docs/Splay Tree.md new file mode 100644 index 0000000..46c47ca --- /dev/null +++ b/docs/Splay Tree.md @@ -0,0 +1,200 @@ + +## splay-tree-rr-sir + +- used here by rr sir, I have no idea how to use it or what it's used in mostly, [RR Sir ABC F Submission](https://atcoder.jp/contests/abc350/submissions/52600529) +- ``` + https://thesobersobber.github.io/CP-Snippets/Splay Tree + ``` +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2466) + +```cpp + +#include +#include + +namespace allocator { + +// Array allocator. +template +struct array { + T v[MAXSIZE], *top; + array() : top(v) {} + T *alloc(const T &val = T()) { return &(*top++ = val); } + void dealloc(T *p) {} +}; + +// Stack-based array allocator. +template +struct stack { + T v[MAXSIZE]; + T *spot[MAXSIZE], **top; + stack() { + for (int i = 0; i < MAXSIZE; ++i) spot[i] = v + i; + top = spot + MAXSIZE; + } + T *alloc(const T &val = T()) { return &(**--top = val); } + void dealloc(T *p) { *top++ = p; } +}; + +} // namespace allocator + +namespace splay { + +// Abstract node struct. +template +struct node { + T *f, *c[2]; + int size; + node() { + f = c[0] = c[1] = nullptr; + size = 1; + } + void push_down() {} + void update() { + size = 1; + for (int t = 0; t < 2; ++t) + if (c[t]) size += c[t]->size; + } +}; + +// Abstract reversible node struct. +template +struct reversible_node : node { + int r; + reversible_node() : node() { r = 0; } + void push_down() { + node::push_down(); + if (r) { + for (int t = 0; t < 2; ++t) + if (node::c[t]) node::c[t]->reverse(); + r = 0; + } + } + void update() { node::update(); } + // Reverse the range of this node. + void reverse() { + std::swap(node::c[0], node::c[1]); + r = r ^ 1; + } +}; + +template > +struct tree { + alloc pool; + T *root; + // Get a new node from the pool. + T *new_node(const T &val = T()) { return pool.alloc(val); } + tree() { + root = new_node(), root->c[1] = new_node(), root->size = 2; + root->c[1]->f = root; + } + // Helper function to rotate node. + void rotate(T *n) { + int v = n->f->c[0] == n; + T *p = n->f, *m = n->c[v]; + if (p->f) p->f->c[p->f->c[1] == p] = n; + n->f = p->f, n->c[v] = p; + p->f = n, p->c[v ^ 1] = m; + if (m) m->f = p; + p->update(), n->update(); + } + // Splay n so that it is under s (or to root if s is null). + void splay(T *n, T *s = nullptr) { + while (n->f != s) { + T *m = n->f, *l = m->f; + if (l == s) + rotate(n); + else if ((l->c[0] == m) == (m->c[0] == n)) + rotate(m), rotate(n); + else + rotate(n), rotate(n); + } + if (!s) root = n; + } + // Get the size of the tree. + int size() { return root->size - 2; } + // Helper function to walk down the tree. + int walk(T *n, int &v, int &pos) { + n->push_down(); + int s = n->c[0] ? n->c[0]->size : 0; + (v = s < pos) && (pos -= s + 1); + return s; + } + // Insert node n to position pos. + void insert(T *n, int pos) { + T *c = root; + int v; + ++pos; + while (walk(c, v, pos), c->c[v] && (c = c->c[v])) + ; + c->c[v] = n, n->f = c, splay(n); + } + // Find the node at position pos. If sp is true, splay it. + T *find(int pos, int sp = true) { + T *c = root; + int v; + ++pos; + while ((pos < walk(c, v, pos) || v) && (c = c->c[v])) + ; + if (sp) splay(c); + return c; + } + // Find the range [posl, posr) on the splay tree. + T *find_range(int posl, int posr) { + T *r = find(posr), *l = find(posl - 1, false); + splay(l, r); + if (l->c[1]) l->c[1]->push_down(); + return l->c[1]; + } + // Insert nn of size nn_size to position pos. + void insert_range(T **nn, int nn_size, int pos) { + T *r = find(pos), *l = find(pos - 1, false), *c = l; + splay(l, r); + for (int i = 0; i < nn_size; ++i) c->c[1] = nn[i], nn[i]->f = c, c = nn[i]; + for (int i = nn_size - 1; i >= 0; --i) nn[i]->update(); + l->update(), r->update(), splay(nn[nn_size - 1]); + } + // Helper function to dealloc a subtree. + void dealloc(T *n) { + if (!n) return; + dealloc(n->c[0]); + dealloc(n->c[1]); + pool.dealloc(n); + } + // Remove from position [posl, posr). + void erase_range(int posl, int posr) { + T *n = find_range(posl, posr); + n->f->c[1] = nullptr, n->f->update(), n->f->f->update(), n->f = nullptr; + dealloc(n); + } +}; + +} // namespace splay + +const int MAXSIZE = 500005; + +struct node: splay::reversible_node { + long long val, val_min, label_add; + node(long long v = 0) : splay::reversible_node(), val(v) { val_min = label_add = 0; } + // Add v to the subtree. + void add(long long v) { + val += v; + val_min += v; + label_add += v; + } + void push_down() { + splay::reversible_node::push_down(); + for (int t = 0; t < 2; ++t) if (c[t]) c[t]->add(label_add); + label_add = 0; + } + void update() { + splay::reversible_node::update(); + val_min = val; + for (int t = 0; t < 2; ++t) if (c[t]) val_min = std::min(val_min, c[t]->val_min); + } +}; + +splay::tree> t; + +``` diff --git a/docs/old-index.html b/docs/old-index.html index 4324808..e202994 100644 --- a/docs/old-index.html +++ b/docs/old-index.html @@ -94,6 +94,7 @@

Index -

  • rr-segtree : best segtree
  • segtree : sextree
  • seive : seive
  • +
  • [splay-tree-rr-sir](https://thesobersobber.github.io/CP-Snippets/Splay Tree) : used here by rr sir, I have no idea how to use it or what it's used in mostly, RR Sir ABC F Submission
  • tokenizer : tokenizer that has no use
  • totient-seive : totient-seive
  • totient : totient
  • diff --git a/docs/tokenizer.md b/docs/tokenizer.md index 65d20e6..ab35b73 100644 --- a/docs/tokenizer.md +++ b/docs/tokenizer.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/tokenizer ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2466) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2661) ```cpp vec(string) tokenizer(string str,char ch) {std::istringstream var((str)); vec(string) v; string t; while(getline((var), t, (ch))) {v.pb(t);} return v;} diff --git a/docs/totient-seive.md b/docs/totient-seive.md index e31831f..1a6bcdc 100644 --- a/docs/totient-seive.md +++ b/docs/totient-seive.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/totient-seive ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2473) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2668) ```cpp for (int i = 1; i < MN; i++) diff --git a/docs/totient.md b/docs/totient.md index ea721e6..68b8086 100644 --- a/docs/totient.md +++ b/docs/totient.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/totient ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2487) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2682) ```cpp long long totient(long long n) { diff --git a/docs/trie.md b/docs/trie.md index 026d874..4da2a7d 100644 --- a/docs/trie.md +++ b/docs/trie.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/trie ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2507) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2702) ```cpp struct Trie{ diff --git a/docs/troll.md b/docs/troll.md index 88286d4..87af888 100644 --- a/docs/troll.md +++ b/docs/troll.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/troll ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2543) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2738) ```cpp // Assembly Generator: gcc -S -o temp.s fileName.cpp diff --git a/docs/two-sat (kosaraju).md b/docs/two-sat (kosaraju).md index 32f5aae..ffeb4d8 100644 --- a/docs/two-sat (kosaraju).md +++ b/docs/two-sat (kosaraju).md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/two-sat (kosaraju) ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2553) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2748) ```cpp /** diff --git a/docs/variadic.md b/docs/variadic.md index 9e55bf1..afd8d33 100644 --- a/docs/variadic.md +++ b/docs/variadic.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/variadic ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2690) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2885) ```cpp #define f(u, args...) [&](auto &&u) { return args; } diff --git a/docs/xor-basis.md b/docs/xor-basis.md index 9a5bcc6..6b32f79 100644 --- a/docs/xor-basis.md +++ b/docs/xor-basis.md @@ -5,7 +5,7 @@ - ``` https://thesobersobber.github.io/CP-Snippets/xor-basis ``` -- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2699) +- [github-snip-file](https://github.com/theSoberSobber/CP-Snippets/blob/main/snippets.json#L2894) ```cpp struct XorBasis{ diff --git a/snippets.json b/snippets.json index 244fa9d..360982b 100644 --- a/snippets.json +++ b/snippets.json @@ -2463,6 +2463,201 @@ ], "description":"seive" }, + "splay-tree-rr-sir": { + "prefix":"Splay Tree", + "body": [ + "", + "#include ", + "#include ", + "", + "namespace allocator {", + "", + "// Array allocator.", + "template ", + "struct array {", + " T v[MAXSIZE], *top;", + " array() : top(v) {}", + " T *alloc(const T &val = T()) { return &(*top++ = val); }", + " void dealloc(T *p) {}", + "};", + "", + "// Stack-based array allocator.", + "template ", + "struct stack {", + " T v[MAXSIZE];", + " T *spot[MAXSIZE], **top;", + " stack() {", + " for (int i = 0; i < MAXSIZE; ++i) spot[i] = v + i;", + " top = spot + MAXSIZE;", + " }", + " T *alloc(const T &val = T()) { return &(**--top = val); }", + " void dealloc(T *p) { *top++ = p; }", + "};", + "", + "} // namespace allocator", + "", + "namespace splay {", + "", + "// Abstract node struct.", + "template ", + "struct node {", + " T *f, *c[2];", + " int size;", + " node() {", + " f = c[0] = c[1] = nullptr;", + " size = 1;", + " }", + " void push_down() {}", + " void update() {", + " size = 1;", + " for (int t = 0; t < 2; ++t)", + " if (c[t]) size += c[t]->size;", + " }", + "};", + "", + "// Abstract reversible node struct.", + "template ", + "struct reversible_node : node {", + " int r;", + " reversible_node() : node() { r = 0; }", + " void push_down() {", + " node::push_down();", + " if (r) {", + " for (int t = 0; t < 2; ++t)", + " if (node::c[t]) node::c[t]->reverse();", + " r = 0;", + " }", + " }", + " void update() { node::update(); }", + " // Reverse the range of this node.", + " void reverse() {", + " std::swap(node::c[0], node::c[1]);", + " r = r ^ 1;", + " }", + "};", + "", + "template >", + "struct tree {", + " alloc pool;", + " T *root;", + " // Get a new node from the pool.", + " T *new_node(const T &val = T()) { return pool.alloc(val); }", + " tree() {", + " root = new_node(), root->c[1] = new_node(), root->size = 2;", + " root->c[1]->f = root;", + " }", + " // Helper function to rotate node.", + " void rotate(T *n) {", + " int v = n->f->c[0] == n;", + " T *p = n->f, *m = n->c[v];", + " if (p->f) p->f->c[p->f->c[1] == p] = n;", + " n->f = p->f, n->c[v] = p;", + " p->f = n, p->c[v ^ 1] = m;", + " if (m) m->f = p;", + " p->update(), n->update();", + " }", + " // Splay n so that it is under s (or to root if s is null).", + " void splay(T *n, T *s = nullptr) {", + " while (n->f != s) {", + " T *m = n->f, *l = m->f;", + " if (l == s)", + " rotate(n);", + " else if ((l->c[0] == m) == (m->c[0] == n))", + " rotate(m), rotate(n);", + " else", + " rotate(n), rotate(n);", + " }", + " if (!s) root = n;", + " }", + " // Get the size of the tree.", + " int size() { return root->size - 2; }", + " // Helper function to walk down the tree.", + " int walk(T *n, int &v, int &pos) {", + " n->push_down();", + " int s = n->c[0] ? n->c[0]->size : 0;", + " (v = s < pos) && (pos -= s + 1);", + " return s;", + " }", + " // Insert node n to position pos.", + " void insert(T *n, int pos) {", + " T *c = root;", + " int v;", + " ++pos;", + " while (walk(c, v, pos), c->c[v] && (c = c->c[v]))", + " ;", + " c->c[v] = n, n->f = c, splay(n);", + " }", + " // Find the node at position pos. If sp is true, splay it.", + " T *find(int pos, int sp = true) {", + " T *c = root;", + " int v;", + " ++pos;", + " while ((pos < walk(c, v, pos) || v) && (c = c->c[v]))", + " ;", + " if (sp) splay(c);", + " return c;", + " }", + " // Find the range [posl, posr) on the splay tree.", + " T *find_range(int posl, int posr) {", + " T *r = find(posr), *l = find(posl - 1, false);", + " splay(l, r);", + " if (l->c[1]) l->c[1]->push_down();", + " return l->c[1];", + " }", + " // Insert nn of size nn_size to position pos.", + " void insert_range(T **nn, int nn_size, int pos) {", + " T *r = find(pos), *l = find(pos - 1, false), *c = l;", + " splay(l, r);", + " for (int i = 0; i < nn_size; ++i) c->c[1] = nn[i], nn[i]->f = c, c = nn[i];", + " for (int i = nn_size - 1; i >= 0; --i) nn[i]->update();", + " l->update(), r->update(), splay(nn[nn_size - 1]);", + " }", + " // Helper function to dealloc a subtree.", + " void dealloc(T *n) {", + " if (!n) return;", + " dealloc(n->c[0]);", + " dealloc(n->c[1]);", + " pool.dealloc(n);", + " }", + " // Remove from position [posl, posr).", + " void erase_range(int posl, int posr) {", + " T *n = find_range(posl, posr);", + " n->f->c[1] = nullptr, n->f->update(), n->f->f->update(), n->f = nullptr;", + " dealloc(n);", + " }", + "};", + "", + "} // namespace splay", + "", + "const int MAXSIZE = 500005;", + "", + "struct node: splay::reversible_node {", + " long long val, val_min, label_add;", + " node(long long v = 0) : splay::reversible_node(), val(v) { val_min = label_add = 0; }", + " // Add v to the subtree.", + " void add(long long v) {", + " val += v;", + " val_min += v;", + " label_add += v;", + " }", + " void push_down() {", + " splay::reversible_node::push_down();", + " for (int t = 0; t < 2; ++t) if (c[t]) c[t]->add(label_add);", + " label_add = 0;", + " } ", + " void update() {", + " splay::reversible_node::update();", + " val_min = val;", + " for (int t = 0; t < 2; ++t) if (c[t]) val_min = std::min(val_min, c[t]->val_min);", + " }", + "};", + "", + "splay::tree> t;", + "" + ], + "description":"used here by rr sir, I have no idea how to use it or what it's used in mostly, [RR Sir ABC F Submission](https://atcoder.jp/contests/abc350/submissions/52600529)" + }, "tokenizer": { "prefix":"tokenizer", "body": [