Skip to the content.

:warning: data_structure/strong_link_cut_tree.hpp

Depends on

Code

#pragma once
#include <cstdint>
#include <data_structure/indexed_splay_tree.hpp>
#include <vector>

template <typename T, auto op, auto e>
struct StrongLinkCutTree : public IndexedSplayTree<T, op, e> {
    using Splay = IndexedSplayTree<T, op, e>;
    using nptr = Splay::nptr;
    std::vector<nptr> node;

    StrongLinkCutTree() {}
    StrongLinkCutTree(const std::vector<std::vector<int>>& g) : StrongLinkCutTree(g, std::vector<T>(g.size(), e())) {}
    StrongLinkCutTree(const std::vector<std::vector<int>>& g, const std::vector<T>& v) {
        for (uint32_t i = 0, siz = v.size(); i < siz; ++i) {
            add(v[i]);
        }
        for (int u = 0, siz = v.size(); u < siz; ++u) {
            for (int v : g[u]) {
                if (u > v) continue;
                link(u, v);
            }
        }
    }

    void add(T x) {
        node.emplace_back(new Splay::node{x, static_cast<int>(node.size())});
    }

    int expose(nptr& ptr) {
        nptr last = ptr;
        while (true) {
            Splay::splay(ptr);
            ptr->right = nullptr;
            Splay::update(ptr);
            if (!ptr->parent) {
                return last->idx;
            }
            last = ptr->parent;
            Splay::splay(ptr->parent);
            ptr->parent->right = ptr;
            Splay::update(ptr->parent);
        }
    }

    void evert(nptr ptr) {
        expose(ptr);
        Splay::toggle(ptr);
    }

    void link(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        evert(v);
        v->parent = u;
    }

    void cut(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        evert(u);
        expose(v);
        v->left->parent = nullptr;
        v->left = nullptr;
        Splay::update(v);
    }

    void set(int U, T x) {
        nptr u = node[U];
        expose(u);
        u->v = x;
        Splay::update(u);
    }

    T operator[](int U) {
        nptr u = node[U];
        expose(u);
        return u->v;
    }

    T operator()(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        evert(u);
        expose(v);
        return v->p;
    }

    int lca(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        expose(u);
        return expose(v);
    }
};
#line 2 "data_structure/strong_link_cut_tree.hpp"
#include <cstdint>
#include <data_structure/indexed_splay_tree.hpp>
#include <vector>

template <typename T, auto op, auto e>
struct StrongLinkCutTree : public IndexedSplayTree<T, op, e> {
    using Splay = IndexedSplayTree<T, op, e>;
    using nptr = Splay::nptr;
    std::vector<nptr> node;

    StrongLinkCutTree() {}
    StrongLinkCutTree(const std::vector<std::vector<int>>& g) : StrongLinkCutTree(g, std::vector<T>(g.size(), e())) {}
    StrongLinkCutTree(const std::vector<std::vector<int>>& g, const std::vector<T>& v) {
        for (uint32_t i = 0, siz = v.size(); i < siz; ++i) {
            add(v[i]);
        }
        for (int u = 0, siz = v.size(); u < siz; ++u) {
            for (int v : g[u]) {
                if (u > v) continue;
                link(u, v);
            }
        }
    }

    void add(T x) {
        node.emplace_back(new Splay::node{x, static_cast<int>(node.size())});
    }

    int expose(nptr& ptr) {
        nptr last = ptr;
        while (true) {
            Splay::splay(ptr);
            ptr->right = nullptr;
            Splay::update(ptr);
            if (!ptr->parent) {
                return last->idx;
            }
            last = ptr->parent;
            Splay::splay(ptr->parent);
            ptr->parent->right = ptr;
            Splay::update(ptr->parent);
        }
    }

    void evert(nptr ptr) {
        expose(ptr);
        Splay::toggle(ptr);
    }

    void link(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        evert(v);
        v->parent = u;
    }

    void cut(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        evert(u);
        expose(v);
        v->left->parent = nullptr;
        v->left = nullptr;
        Splay::update(v);
    }

    void set(int U, T x) {
        nptr u = node[U];
        expose(u);
        u->v = x;
        Splay::update(u);
    }

    T operator[](int U) {
        nptr u = node[U];
        expose(u);
        return u->v;
    }

    T operator()(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        evert(u);
        expose(v);
        return v->p;
    }

    int lca(int U, int V) {
        nptr u = node[U];
        nptr v = node[V];
        expose(u);
        return expose(v);
    }
};
Back to top page