Skip to content

Commit

Permalink
feat: upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Jan 3, 2025
1 parent 3550a78 commit 2b0c44a
Show file tree
Hide file tree
Showing 86 changed files with 67,415 additions and 185 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ jobs:
cache-pip: true

- name: Get storage information before cleaning up
if: ${{ matrix.type == 'huge' }}
run: |
echo "::group::free"
free
Expand All @@ -141,12 +142,14 @@ jobs:
echo "::endgroup::"
- name: Clean up
if: ${{ matrix.type == 'huge' }}
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
sudo docker builder prune -a
- name: Get storage information before cleaning up
if: ${{ matrix.type == 'huge' }}
run: |
echo "::group::free"
free
Expand Down
3 changes: 3 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ notebook:
- blossomw: 带权带花树
code_ext: hpp
test_ext: cpp
- min_cycle_mean: 有向图最小平均权值圈
code_ext: hpp
test_ext: cpp
tree:
- tree:
code_ext: hpp
Expand Down
11 changes: 11 additions & 0 deletions notebook.bib
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,14 @@ @article{lemire2019fast
month = jan,
pages = {1--12}
}

@article{karp1978characterization,
title = {A characterization of the minimum cycle mean in a digraph},
author = {Karp, Richard M},
journal = {Discrete mathematics},
volume = {23},
number = {3},
pages = {309--311},
year = {1978},
publisher = {Elsevier}
}
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
click==8.1.8
colorama==0.4.6
coloredlogs==15.0.1
competitive-verifier==3.2.2
competitive-verifier==3.3.0
humanfriendly==10.0
online-judge-verify-helper==5.6.0
pycodestyle==2.12.1
Expand Down
28 changes: 21 additions & 7 deletions src/code/ds/hld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#include "segtree.hpp"

namespace tifa_libs::ds {

template <class T, auto op, auto e, class F = T, auto mapping = op, auto composition = e, auto id = e>
namespace hld_impl_ {
template <bool enable_tag, class T, auto op, class F, auto mapping, auto composition>
class hld {
segtree<T, op, e, F, mapping, composition, id> t;
segtree_impl_::segtree<enable_tag, T, op, F, mapping, composition> t;

public:
using tree_info_t = graph::tree_dfs_info<graph::tree, graph::tdi_dfn, graph::tdi_maxson, graph::tdi_dep, graph::tdi_fa>;
Expand All @@ -19,9 +19,9 @@ class hld {
tree_info_t info;
vecu top;

CEXP hld(graph::tree CR tr, tree_info_t CR info_) : t(), tr(tr), info{info_} { top = graph::tree_top<true>(tr, info.dfn, info.maxson); }
CEXPE hld(graph::tree CR tr) : hld(tr, tree_info_t(tr)) {}
CEXP hld(graph::tree CR tr, tree_info_t CR info_, spn<T> a) : hld(tr, info_) {
CEXP hld(cT_(T) e, cT_(F) id, graph::tree CR tr, tree_info_t CR info_) : t(e, id), tr(tr), info{info_} { top = graph::tree_top<true>(tr, info.dfn, info.maxson); }
CEXP hld(cT_(T) e, cT_(F) id, graph::tree CR tr) : hld(e, id, tr, tree_info_t(tr)) {}
CEXP hld(cT_(T) e, cT_(F) id, graph::tree CR tr, tree_info_t CR info_, spn<T> a) : hld(e, id, tr, info_) {
vec<T> b(a.size());
flt_ (u32, i, 0, (u32)a.size()) b[info.dfn[i]] = a[i];
build(b);
Expand Down Expand Up @@ -50,7 +50,7 @@ class hld {
CEXP void subtree_set(u32 u, cT_(T) f) { t.set(info.dfn[u], info.dfn[u] + info.sz[u], f); }
CEXP void node_set(u32 u, cT_(T) f) { t.set(info.dfn[u] + 1, f); }
CEXP T chain_query(u32 u, u32 v) {
T ret = e();
T ret = t.E;
while (top[u] != top[v]) {
if (info.dep[top[u]] < info.dep[top[v]]) swap(u, v);
ret = op(ret, t.query(info.dfn[top[u]], info.dfn[u] + 1)), u = info.fa[top[u]];
Expand All @@ -61,6 +61,20 @@ class hld {
CEXP T subtree_query(u32 u) { return t.query(info.dfn[u], info.dfn[u] + info.sz[u]); }
CEXP T node_query(u32 u) { return t.query(info.dfn[u]); }
};
} // namespace hld_impl_

template <class T, auto op, class F, auto mapping, auto composition>
using hld = hld_impl_::hld<true, T, op, F, mapping, composition>;
template <class T, auto op>
class hld_notag : public hld_impl_::hld<false, T, op, T, op, op> {
using base = hld_impl_::hld<false, T, op, T, op, op>;

public:
CEXP hld_notag(cT_(T) e, graph::tree CR tr, base::tree_info_t CR info) : base(e, e, tr, info) {}
template <class V>
CEXP hld_notag(cT_(T) e, graph::tree CR tr) : base(e, e, tr) {}
CEXP hld_notag(cT_(T) e, graph::tree CR tr, base::tree_info_t CR info, spn<T> a) : base(e, e, tr, info, a) {}
};

} // namespace tifa_libs::ds

Expand Down
33 changes: 21 additions & 12 deletions src/code/ds/segtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,27 @@

namespace tifa_libs::ds {
namespace segtree_impl_ {
template <bool enable_tag, class T, auto op, auto e, class F, auto mapping, auto composition, auto id>
template <bool enable_tag, class T, auto op, class F, auto mapping, auto composition>
requires requires(T val, T new_val, F tag, F new_tag) {
{ e() } -> std::same_as<T>;
{ op(val, new_val) } -> std::same_as<T>;
{ mapping(val, tag) } -> std::same_as<T>;
{ composition(tag, new_tag) } -> std::same_as<F>;
{ id() } -> std::same_as<F>;
}
class segtree {
static inline const T E = e();
static inline const F ID = id();
struct segtree {
const T E;
const F ID;

private:
u32 sz, lbn, n;
vec<T> val;
vec<F> tag;
vecb vset;

public:
CEXP segtree(cT_(T) e, cT_(F) id) : E(e), ID(id), sz(0), lbn(0), n(0), val{}, tag{}, vset{} {}
template <class V>
CEXPE segtree(V &&a) { reset(std::forward<V>(a)); }
CEXPE segtree(u32 n = 0) : segtree(vec<T>(n, E)) {}
CEXP segtree(cT_(T) e, cT_(F) id, V &&a) : segtree(e, id) { reset(std::forward<V>(a)); }
CEXP segtree(cT_(T) e, cT_(F) id, u32 n) : segtree(e, id) { reset(vec<T>(n, e)); }

template <class V>
CEXP void reset(V &&a) {
Expand Down Expand Up @@ -157,10 +158,18 @@ class segtree {
};
} // namespace segtree_impl_

template <class T, auto op, auto e, class F, auto mapping, auto composition, auto id>
using segtree = segtree_impl_::segtree<true, T, op, e, F, mapping, composition, id>;
template <class T, auto op, auto e>
using segtree_notag = segtree_impl_::segtree<false, T, op, e, T, op, op, e>;
template <class T, auto op, class F, auto mapping, auto composition>
using segtree = segtree_impl_::segtree<true, T, op, F, mapping, composition>;
template <class T, auto op>
class segtree_notag : public segtree_impl_::segtree<false, T, op, T, op, op> {
using base = segtree_impl_::segtree<false, T, op, T, op, op>;

public:
CEXPE segtree_notag(cT_(T) e) : base(e, e) {}
template <class V>
CEXP segtree_notag(cT_(T) e, V &&a) : base(e, e, std::forward<V>(a)) {}
CEXP segtree_notag(cT_(T) e, u32 n) : base(e, e, n) {}
};

} // namespace tifa_libs::ds

Expand Down
26 changes: 10 additions & 16 deletions src/code/ds/segtree_ctor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,24 @@ CEXP P<T> pset_(P<T> CR x, cT_(T) y) { return {x.l * y, x.l}; }
template <class T>
CEXP P<T> padd_(P<T> CR x, cT_(T) y) { return {x.v + x.l * y, x.l}; }
template <class T>
CEXP T e_() { return T(0); }
template <class T, T val>
CEXP T v_() { return val; }
CEXP auto segtl_addmax_ctor(cT_(T) ninf, spn<T> a) { return segtree<T, max_<T>, T, add_<T>, add_<T>>(ninf, T(0), a); }
template <class T>
CEXP P<T> pe_() { return {0, 0}; }
template <class T, T NINF>
CEXP auto segtl_addmax_ctor(spn<T> a) { return segtree<T, max_<T>, v_<T, NINF>, T, add_<T>, add_<T>, e_<T>>(a); }
template <class T, T INF>
CEXP auto segtl_addmin_ctor(spn<T> a) { return segtree<T, min_<T>, v_<T, INF>, T, add_<T>, add_<T>, e_<T>>(a); }
CEXP auto segtl_addmin_ctor(cT_(T) inf, spn<T> a) { return segtree<T, min_<T>, T, add_<T>, add_<T>>(inf, T(0), a); }
template <class T>
CEXP auto segtl_addsum_ctor(vec<T> CR a) {
vec<P<T>> b(a.size());
flt_ (u32, i, 0, (u32)a.size()) b[i] = {a[i], 1};
return segtree<P<T>, add_<P<T>>, pe_<T>, T, padd_<T>, add_<T>, e_<T>>(b);
return segtree<P<T>, add_<P<T>>, T, padd_<T>, add_<T>>(P<T>{0, 0}, T(0), b);
}
template <class T, T NINF>
CEXP auto segtl_setmax_ctor(spn<T> a) { return segtree<T, max_<T>, v_<T, NINF>, T, set_<T>, set_<T>, v_<T, NINF>>(a); }
template <class T, T INF>
CEXP auto segtl_setmin_ctor(spn<T> a) { return segtree<T, min_<T>, v_<T, INF>, T, set_<T>, set_<T>, v_<T, INF>>(a); }
template <class T, T DEF_VAL>
CEXP auto segtl_setsum_ctor(spn<T> a) {
template <class T>
CEXP auto segtl_setmax_ctor(cT_(T) ninf, spn<T> a) { return segtree<T, max_<T>, T, set_<T>, set_<T>>(ninf, ninf, a); }
template <class T>
CEXP auto segtl_setmin_ctor(cT_(T) inf, spn<T> a) { return segtree<T, min_<T>, T, set_<T>, set_<T>>(inf, inf, a); }
template <class T>
CEXP auto segtl_setsum_ctor(cT_(T) def_val, spn<T> a) {
vec<P<T>> b(a.size());
flt_ (u32, i, 0, (u32)a.size()) b[i] = {a[i], 1};
return segtree<P<T>, add_<P<T>>, pe_<T>, T, pset_<T>, set_<T>, v_<T, DEF_VAL>>(b);
return segtree<P<T>, add_<P<T>>, T, pset_<T>, set_<T>>(P<T>{0, 0}, def_val, b);
}
} // namespace segtree_ctor_impl_

Expand Down
4 changes: 2 additions & 2 deletions src/code/geo2d/point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ struct point {

friend std::istream &operator>>(std::istream &is, point &p) { return is >> p.x >> p.y; }
friend std::ostream &operator<<(std::ostream &os, point CR p) { return os << p.x << ' ' << p.y; }
// s * r + t * (1 - r)
// s + (t - s) * r
template <std::floating_point T>
friend CEXP point lerp(point CR s, point CR t, T r) { return s * r + t * (1 - r); }
friend CEXP point lerp(point CR s, point CR t, T r) { return s + (t - s) * r; }
friend CEXP point mid_point(point CR s, point CR t) { return lerp(s, t, .5); }
CEXP point &operator+=(arithm_c auto n) { return this->x += n, this->y += n, *this; }
CEXP point &operator-=(arithm_c auto n) { return this->x -= n, this->y -= n, *this; }
Expand Down
8 changes: 3 additions & 5 deletions src/code/geo3d/point3d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ struct point3d {

friend std::istream &operator>>(std::istream &is, point3d &p) { return is >> p.x >> p.y >> p.z; }
friend std::ostream &operator<<(std::ostream &os, point3d CR p) { return os << p.x << ' ' << p.y << ' ' << p.z; }
// s * r + t * (1 - r)
friend CEXP point3d lerp(point3d CR s, point3d CR t, FP r) {
static_assert(std::floating_point<FP>);
return s * r + t * (1 - r);
}
// s + (t - s) * r
template <std::floating_point T>
friend CEXP point3d lerp(point3d CR s, point3d CR t, T r) { return s + (t - s) * r; }
friend CEXP point3d mid_point(point3d CR s, point3d CR t) { return lerp(s, t, .5); }
CEXP point3d &operator+=(FP n) { return this->x += n, this->y += n, this->z += n, *this; }
CEXP point3d operator+(FP n) const { return point3d(*this) += n; }
Expand Down
2 changes: 1 addition & 1 deletion src/code/graph/alists.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class alists {
CEXP void add_arc(u32 u, Ts&&... args) { b.emplace_back(u, ET{std::forward<Ts>(args)...}), ++h[u]; }
CEXP void build() {
if (cnt_arc) return;
std::partial_sum(h.begin(), h.end(), h.begin());
std::inclusive_scan(h.begin(), h.end(), h.begin());
for (e.resize(cnt_arc = (u32)b.size()); auto CR[u, e] : b) e[--h[u]] = e;
if CEXP (with_deg)
for (auto CR[u, e] : b) ++deg_out[u], ++deg_in[e.to];
Expand Down
34 changes: 23 additions & 11 deletions src/code/graph/bm.hpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
#ifndef TIFALIBS_GRAPH_BM
#define TIFALIBS_GRAPH_BM

#include "../math/isqrt.hpp"
#include "../util/traits.hpp"

namespace tifa_libs::graph {

// cb_relax(now, to)
template <adjlistw_c G, class F, class T = TPN G::w_t>
requires(!uint_c<T>) && requires(F relex, u32 now, u32 to) { relex(now, to); }
std::optional<vec<T>> bellman_ford(G CR g, u32 s, F &&cb_relax, T INF = std::numeric_limits<T>::max() / 2 - 1) {
vec<T> dis(g.size(), INF);
vecb vis(g.size());
vecu dep(g.size());
std::queue<u32> q({s});
// @return false if negative cycle detected
template <adjlistw_c G, class F>
requires(!uint_c<TPN G::w_t>) && requires(F relex, u32 now, u32 to) { relex(now, to); }
bool bellman_ford(G CR g, u32 s, F &&cb_relax, vec<TPN G::w_t> &dis) {
const u32 n = g.size(), sn = math::isqrt(n);
assert(dis.size() == n);
vecb vis(n);
vecu dep(n);
std::deque<u32> q({s});
auto upd_q = [&] {
if (q.size() >= 2 && dis[q.front()] > dis[q.back()]) swap(q.front(), q.back());
};
dis[s] = 0, vis[s] = true, dep[s] = 1;
while (!q.empty()) {
const u32 u = q.front();
for (q.pop(), vis[u] = false; auto [v, w] : g[u])
for (q.pop_front(), upd_q(), vis[u] = false; auto [v, w] : g[u])
if (dis[u] + w < dis[v]) {
if (cb_relax(u, v), dis[v] = dis[u] + w; vis[v]) continue;
if (++dep[v] > g.size()) return {};
vis[v] = true, q.push(v);
if (++dep[v] > n) return false;
vis[v] = true, ((1 < dep[v] && dep[v] < sn) || dis[v] < TPN G::w_t(q.size() ? dis[q.front()] : 0) ? q.push_front(v) : q.push_back(v)), upd_q();
}
}
return dis;
return true;
}
// cb_relax(now, to)
template <adjlistw_c G, class F>
std::optional<vec<TPN G::w_t>> bellman_ford(G CR g, u32 s, F &&cb_relax, TPN G::w_t INF = std::numeric_limits<TPN G::w_t>::max() / 2 - 1) {
vec dis(g.size(), INF);
return bellman_ford(g, s, std::forward<F>(cb_relax), dis) ? std::optional{dis} : std::nullopt;
}

} // namespace tifa_libs::graph
Expand Down
28 changes: 28 additions & 0 deletions src/code/graph/min_cycle_mean.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef TIFALIBS_GRAPH_MIN_CYCLE_MEAN
#define TIFALIBS_GRAPH_MIN_CYCLE_MEAN

#include "../util/util.hpp"

namespace tifa_libs::graph {

template <class T>
CEXP T min_cycle_mean(vec<edge_t<T>> CR edges, u32 n, T INF = std::numeric_limits<T>::max() / 2 - 1) {
vec<T> d(n + 1), d2(n + 1);
for (u32 i = 0; i < n; ++i, std::swap(d, d2))
for (std::fill_n(d.begin(), n, INF); auto [w, u, v] : edges) d[v] = std::min(d[v], d2[u] + w);
vec<T> dn = d2, mx(n + 1);
T ans = INF;
std::ranges::transform(dn, mx.begin(), [&](auto x) { return x / n; });
std::ranges::fill(d2, 0);
for (u32 i = 1; i < n; ++i, std::swap(d, d2)) {
for (std::fill_n(d.begin(), n, INF); auto [w, u, v] : edges) d[v] = std::min(d[v], d2[u] + w);
flt_ (u32, j, 0, n) mx[j] = std::max(mx[j], (dn[j] - d[j]) / (n - i));
}
flt_ (u32, i, 0, n)
if (dn[i] < INF) ans = std::min(ans, mx[i]);
return ans;
}

} // namespace tifa_libs::graph

#endif
2 changes: 1 addition & 1 deletion src/code/graph/sat2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class sat2 {
CEXP void add(u32 x, bool vx, u32 y, bool vy) { x = x * 2 + vx, y = y * 2 + vy, e.emplace_back(x ^ 1, y), e.emplace_back(y ^ 1, x), ++st[x ^ 1], ++st[y ^ 1]; }
// @return a, a_i == 1 if c_i is true else a_i == 0
CEXP std::optional<vecu> solve() {
std::partial_sum(st.begin(), st.end(), st.begin()), *std::move_backward(st.begin(), st.end() - 1, st.end()) = 0;
std::inclusive_scan(st.begin(), st.end(), st.begin()), *std::move_backward(st.begin(), st.end() - 1, st.end()) = 0;
vecu to(e.size());
for (auto CR[u, v] : e) to[st[u]++] = v;
*std::move_backward(st.begin(), st.end() - 1, st.end()) = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/code/util/ndvec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct ndvec : vec<T> {
CEXP void resize(Ts &&...args) {
static_assert(sizeof...(args) == N);
u32 n = 0;
((idxs[n++] = (u32)args), ...), idxs[N] = 1, partial_sum(idxs.rbegin(), idxs.rend(), idxs.rbegin(), std::multiplies<>{}), vec<T>::resize(idxs[0]);
((idxs[n++] = (u32)args), ...), idxs[N] = 1, inclusive_scan(idxs.rbegin(), idxs.rend(), idxs.rbegin(), std::multiplies<>{}), vec<T>::resize(idxs[0]);
}
template <class... Ts>
CEXP T &operator()(Ts &&...args) {
Expand Down
Loading

0 comments on commit 2b0c44a

Please sign in to comment.