Skip to content

Commit

Permalink
feat: upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Mar 3, 2025
1 parent 65e8d8b commit ef10317
Show file tree
Hide file tree
Showing 34 changed files with 401 additions and 27 deletions.
21 changes: 18 additions & 3 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,21 @@ notebook:
- tsearch: 三分
code_ext: hpp
test_ext: cpp
- knapsack_01: 01 背包
code_ext: hpp
test_ext: cpp
- knapsack_mixed: 混合背包
code_ext: hpp
test_ext: cpp
- knapsack_mixed_huge: 混合背包(贪心)
code_ext: hpp
test_ext: cpp
- lis: 最长上升子序列
code_ext: hpp
test_ext: cpp
- lev_dis: Levenshtein 距离
code_ext: hpp
test_ext: cpp
- hoverline: 悬线法
code_ext: hpp
test_ext: cpp
Expand All @@ -482,13 +494,16 @@ notebook:
- smawk: SMAWK 算法
code_ext: hpp
test_ext: cpp
- astar: A* 算法
- larsch: LARSCH 算法
code_ext: hpp
test_ext: cpp
- simplex: 单纯形法
- larsch_2d: LARSCH 算法(2D)
code_ext: hpp
test_ext: cpp
- knapsack_mixed: 混合背包
- astar: A* 算法
code_ext: hpp
test_ext: cpp
- simplex: 单纯形法
code_ext: hpp
test_ext: cpp
graph:
Expand Down
19 changes: 19 additions & 0 deletions notebook.bib
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,22 @@ @article{karp1978characterization
year = {1978},
publisher = {Elsevier}
}

@article{larmore1991line,
title = {On-line dynamic programming with applications to the prediction of RNA secondary structure},
author = {Larmore, Lawrence L and Schieber, Baruch},
journal = {Journal of Algorithms},
volume = {12},
number = {3},
pages = {490--515},
year = {1991},
publisher = {Elsevier}
}

@inproceedings{aggarwal1986geometric,
title = {Geometric applications of a matrix searching algorithm},
author = {Aggarwal, Alok and Klawe, Maria and Moran, Shlomo and Shor, Peter and Wilber, Robert},
booktitle = {Proceedings of the second annual symposium on Computational geometry},
pages = {285--292},
year = {1986}
}
21 changes: 4 additions & 17 deletions src/code/ds/mono_stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,15 @@ class mono_stack {
static CEXP Comp compare{};

vec<T> s;
template <bool use_bf = false>
CEXP auto find_(cT_(T) x) NE {
if CEXP (use_bf) {
auto it = s.rbegin();
while (it != s.rend() && compare(x, *it)) ++it;
return (--it).base();
} else return upper_bound(s, x, compare);
}

public:
CEXPE mono_stack() NE = default;

template <bool use_bf = false>
CEXP void pop_greater(cT_(T) x) NE { s.erase(find_<use_bf>(x), s.end()); }
CEXP void push_nocheck(cT_(T) x) NE { s.push_back(x); }
template <bool use_bf = false>
CEXP void push(cT_(T) x) NE { pop_greater<use_bf>(x), s.push_back(x); }
template <bool use_bf = false>
CEXP void insert(cT_(T) x) NE {
if (auto it = find_<use_bf>(x); it == s.end()) s.push_back(x);
else *it = x;
CEXP void pop_greater(cT_(T) x) NE {
while (!s.empty() && compare(x, s.back())) s.pop_back();
}
CEXP void push_nocheck(cT_(T) x) NE { s.push_back(x); }
CEXP void push(cT_(T) x) NE { pop_greater(x), s.push_back(x); }
CEXP T CR top() CNE { return s.back(); }
CEXP u32 size() CNE { return (u32)s.size(); }
};
Expand Down
59 changes: 59 additions & 0 deletions src/code/opt/knapsack_01.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef TIFALIBS_OPT_KNAPSACK_01
#define TIFALIBS_OPT_KNAPSACK_01

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

namespace tifa_libs::opt {

//@param a a[i]={value, weight}
//@param W max weight
//@return max total value while total weight <= W
template <int_c T>
CEXP T knapsack_01(vecpt<T> CR a, T W) NE {
const T vs = [k = std::views::keys(a)] { return std::reduce(k.begin(), k.end(), T{}); }();
const T _1 = W, _2 = vs,
_3 = T(a.size() >= 128 ? -1_u64 : 1_u64 << ((a.size() + 1) / 2)),
_min = min({_1, _2, _3});
assert(0_isz <= (isz)_min && (usz)_min * a.size() < (usz)1e9);
if (_min == _1) {
vec<T> dp(W + 1);
for (auto [s, t] : a)
for (u32 j = u32(W - t); (i32)j >= 0; --j) dp[j + t] = max(dp[j + t], dp[j] + s);
return max(dp);
} else if (const T inf = to_uint_t<T>(-1) / 2 - 1; _min == _2) {
vec<T> dp(vs + 1, inf);
dp[0] = 0;
for (auto [s, t] : a)
for (u32 j = u32(vs - s); (i32)j >= 0; --j) dp[j + s] = min(dp[j + s], dp[j] + t);
T ans = 0;
flt_ (T, i, 0, T(vs + 1))
if (dp[i] <= W) ans = max(ans, i);
return ans;
} else {
auto f = [&](u32 l, u32 r) {
vecpt<T> res(1 << (r - l));
res[0] = {0, 0};
flt_ (u32, i, 0, r - l)
flt_ (u32, j, 0, 1 << i) {
auto&& [v, w] = a[l + i];
res[je + j] = {res[j].first + w, res[j].second + v};
}
sort(res);
flt_ (u32, i, 1, (u32)res.size()) res[i].second = max(res[i].second, res[i - 1].second);
return res;
};
auto l = f(0, (u32)a.size() / 2), r = f((u32)a.size() / 2, (u32)a.size());
reverse(l), r.emplace_back(inf, inf);
T ans = 0;
u32 id = -1_u32;
for (auto& [t, s] : l) {
while (t + r[id + 1].first <= W) ++id;
if (~id) ans = max(ans, s + r[id].second);
}
return ans;
}
}

} // namespace tifa_libs::opt

#endif
42 changes: 42 additions & 0 deletions src/code/opt/knapsack_mixed_huge.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef TIFALIBS_OPT_KNAPSACK_MIXED_HUGE
#define TIFALIBS_OPT_KNAPSACK_MIXED_HUGE

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

namespace tifa_libs::opt {

//@param a a[i]={value, weight, count}
//@param W max weight
//@return max total value while total weight <= W
template <int_c T>
CEXP T knapsack_mixed_huge(vec<pt3<T>> a, T W) NE {
const u32 n = (u32)a.size();
assert(n < 500);
const u32 lim = [k = max(n, 50_u32)] { return k * k * k + 1; }();
vec<T> dp(lim + 1, to_uint_t<T>(-1) / 2 - 1);
dp[0] = 0;
for (auto& [v, w, num] : a) {
T have = min(num, (T)n);
num -= have;
for (T k = 1; k = min(have, k), have; have -= k, k <<= 1)
for (u32 j = lim - 1; (T)j >= v * k; --j) dp[j] = min(dp[j], dp[j - v * k] + w * k);
}
vecu id(n);
std::iota(id.begin(), id.end(), 0), sort(id, [&](auto x, auto y) { return a[x]._0 * a[y]._1 > a[y]._0 * a[x]._1; });
T ans = 0;
flt_ (u32, j, 0, lim + 1) {
if (W < dp[j]) continue;
T rest = W - dp[j], now = j;
for (auto i : id) {
auto [v, w, num] = a[i];
T div = min(num, rest / w);
rest -= div * w, now += div * v;
}
ans = max(ans, now);
}
return ans;
}

} // namespace tifa_libs::opt

#endif
31 changes: 31 additions & 0 deletions src/code/opt/larsch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef TIFALIBS_OPT_LARSCH
#define TIFALIBS_OPT_LARSCH

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

namespace tifa_libs::opt {

template <arithm_c T, class Func>
requires requires(Func f, u32 x, u32 y) { {f(x,y)}->std::same_as<T>; }
CEXP vec<T> larsch(u32 n, Func&& w, T inf = inf_v<T>) NE {
vec<T> dp(n + 1, inf);
vecu x(n + 1);
auto chk = [&](u32 from, u32 to) {
if (from >= to) return;
if (T cost = w(from, to); dp[from] + cost < dp[to]) dp[to] = dp[from] + cost, x[to] = from;
};
auto f = [&](auto&& f, u32 l, u32 r) -> void {
if (l + 1 >= r) return;
u32 m = l + (r - l) / 2;
for (u32 i = x[l]; i <= x[r]; i++) chk(i, m);
f(f, l, m);
for (u32 i = l + 1; i <= m; i++) chk(i, r);
f(f, m, r);
};
dp[0] = 0, chk(0, n), f(f, 0, n);
return dp;
};

} // namespace tifa_libs::opt

#endif
27 changes: 27 additions & 0 deletions src/code/opt/larsch_2d.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef TIFALIBS_OPT_LARSCH_2D
#define TIFALIBS_OPT_LARSCH_2D

#include "../util/traits.hpp"
#include "smawk.hpp"

namespace tifa_libs::opt {

template <arithm_c T, class Func>
requires requires(Func f, u32 x, u32 y) { {f(x,y)}->std::same_as<T>; }
CEXP vec<T> larsch_2d(u32 n, Func&& w, T inf = inf_v<T>) NE {
using W = to_bigger_t<T>;
vec<W> dp(n + 1, inf_v<W>);
vec<T> ans(n + 1, inf);
dp[0] = 0;
auto f = [&](u32 j, u32 i) -> W { return i < j ? dp[i] + w(i, j) : inf_v<W>; };
flt_ (u32, d, 1, n) {
auto argmin = smawk(n + 1, n + 1, [&](u32 i, u32 j, u32 k) { return f(i, j) <= f(i, k); });
for (u32 i = n; i >= d; --i) dp[i] = dp[argmin[i]] + w(argmin[i], i);
ans[d] = (T)dp[n];
}
return ans;
};

} // namespace tifa_libs::opt

#endif
22 changes: 22 additions & 0 deletions src/code/opt/lev_dis.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef TIFALIBS_OPT_LEV_DIS
#define TIFALIBS_OPT_LEV_DIS

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

namespace tifa_libs::opt {

//@return ans[i][j] = lev(a[0..i), b[0..j))
template <common_range T>
CEXP vvecu lev_dis(T CR a, T CR b) NE {
const u32 n = (u32)a.size(), m = (u32)b.size();
vvecu ans(n + 1, vecu(m + 1));
flt_ (u32, i, 0, n + 1) ans[i][0] = i;
flt_ (u32, i, 0, m + 1) ans[0][i] = i;
flt_ (u32, i, 1, n + 1)
flt_ (u32, j, 1, m + 1) ans[i][j] = min({ans[i - 1][j - 1] + !(a[i - 1] == b[j - 1]), ans[i][j - 1] + 1, ans[i - 1][j] + 1});
return ans;
}

} // namespace tifa_libs::opt

#endif
4 changes: 4 additions & 0 deletions src/doc_md/opt/knapsack_01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: knapsack_01
documentation_of: //src/code/opt/knapsack_01.hpp
---
4 changes: 4 additions & 0 deletions src/doc_md/opt/knapsack_mixed_huge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: knapsack_mixed_huge
documentation_of: //src/code/opt/knapsack_mixed_huge.hpp
---
4 changes: 4 additions & 0 deletions src/doc_md/opt/larsch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: larsch
documentation_of: //src/code/opt/larsch.hpp
---
4 changes: 4 additions & 0 deletions src/doc_md/opt/larsch_2d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: larsch_2d
documentation_of: //src/code/opt/larsch_2d.hpp
---
4 changes: 4 additions & 0 deletions src/doc_md/opt/lev_dis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: lev_dis
documentation_of: //src/code/opt/lev_dis.hpp
---
4 changes: 1 addition & 3 deletions src/doc_tex/opt/alpha_beta.tex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@

最好 \(O\left(\sqrt{b^d}\right)\), 最坏 \(O\left(b^d\right)\), 其中 \(b\) 为结点的最大出度, \(d\) 为树的深度.

\paragraph{参考文献}

\cite{enwiki:1188156145}
\paragraph{参考文献} \cite{enwiki:1188156145}
1 change: 1 addition & 0 deletions src/doc_tex/opt/knapsack_01.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
\paragraph{复杂度} \(O\left(N\min\left\{W , \sum_i v_i , 2^{\frac{N}{2}}\right\}\right)\)
1 change: 1 addition & 0 deletions src/doc_tex/opt/knapsack_mixed_huge.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
适用于物品个数和价值均较小 (\(\leq 50\)) 且总容量较大 (\(10^9\)) 的情况
13 changes: 13 additions & 0 deletions src/doc_tex/opt/larsch.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
\fullref{sec:smawk-算法} 的变体

\paragraph{输入} Monge 函数 \(w(x,y)\), 范围 \([0,n]\times[0,n]\)

\paragraph{输出} \(a\), 其中 \(a_i=\texttt{dp}(i)\), \(\texttt{dp}(0)=0\), \(\texttt{dp}(i)=\min_{0\leq j<i}\{\texttt{dp}(j)+w(j,i)\},~(i>0)\)

易知 \(A\) 是 Monge 矩阵

\paragraph{复杂度} \(O(n\log n)\)

\paragraph{参考链接} \qrcode{https://www.itcsc.cuhk.edu.hk/Winter_School/Winter_School_2010/Title_Abstract/PPT_Mordecai.pdf} \qrcode{https://www.cse.ust.hk/faculty/golin/Talks/Revisiting_Monge.pdf} \qrcode{https://noshi91.hatenablog.com/entry/2023/02/18/005856}

\paragraph{参考文献} \cite{larmore1991line}
7 changes: 7 additions & 0 deletions src/doc_tex/opt/larsch_2d.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
\paragraph{输入} Monge 函数 \(w(x,y)\), 范围 \([0,n]\times[0,n]\)

\paragraph{输出} \(a\), 其中 \(a_d=\texttt{dp}(n,d)\), \(\texttt{dp}(0,d)=0\), \(\texttt{dp}(i,d)=\min_{0\leq j<i}\{\texttt{dp}(j,d-1)+w(j,i)\},~(i>0)\)

\paragraph{参考链接} \qrcode{https://www.itcsc.cuhk.edu.hk/Winter_School/Winter_School_2010/Title_Abstract/PPT_Mordecai.pdf} \qrcode{https://www.cse.ust.hk/faculty/golin/Talks/Revisiting_Monge.pdf}

\paragraph{参考文献} \cite{larmore1991line}
9 changes: 9 additions & 0 deletions src/doc_tex/opt/lev_dis.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
对两个序列 \(a\), \(b\), 其 Levenshtein 距离 \(\operatorname{lev}(a,b)\) 定义为通过对 \(a\) 进行 (插入, 删除, 修改) 单个元素使其变为 \(b\) 的最少操作次数. 令 \(a'\) 表示 \(a\) 删除第一个元素后的序列, 则

\[
\operatorname{lev}(a,b)=\begin{cases}
\max\{|a|,|b|\}, & |a|=0 ~\text{or}~ |b|=0, \\
\operatorname{lev}(a',b'), & a_0=b_0, \\
1+\min\{\operatorname{lev}(a',b),\operatorname{lev}(a,b'),\operatorname{lev}(a',b')\}, & \text{otherwise}.
\end{cases}
\]
14 changes: 10 additions & 4 deletions src/doc_tex/opt/smawk.tex
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
用于计算满足如下条件的矩阵 \(a\) 每行的 \(\operatorname{argmin}\):
用于计算满足如下条件 (Monotone) 的矩阵 \(A\) 每行的 \(\operatorname{argmin}\):

\begin{center}
\(h(r) = \operatorname{argmin}_i a_{r,i}\), 则 \(h\) 单调不降
\(h(r) = \max \operatorname{argmin}_i A_{r,i}\), 则 \(h\) 单调不降
\end{center}

不难发现可以分治: 对当前矩阵, 找到中间一行的 \(\operatorname{argmin}\), 然后就可根据这个将矩阵分为更小的两个矩阵

如果 Monotone 矩阵 \(A\) 还满足任意 \(2\times 2\) 的子矩阵都是 Monotone 的, 则称 \(A\) 是 Totally monotone 的

如果 Monotone 矩阵 \(A\) 还满足 \(\forall i,j,~A_{i,j}+A_{i+1,j+1}\leq A_{i+1,j}+A_{i,j+1}\), 则称 \(A\) 是 Monge 的

显然若 \(A\) 是 Monge 的则一定是 Totally monotone 的

\paragraph{复杂度} \(O(c(1+\log(r/c)))\), 其中 \(r\) 为矩阵行数, \(c\) 为矩阵列数

\paragraph{参考文献}
\paragraph{参考链接} \qrcode{https://www.itcsc.cuhk.edu.hk/Winter_School/Winter_School_2010/Title_Abstract/PPT_Mordecai.pdf} \qrcode{https://www.cse.ust.hk/faculty/golin/Talks/Revisiting_Monge.pdf}

\cite{enwiki:1033199110}
\paragraph{参考文献} \cite{aggarwal1986geometric} \cite{enwiki:1033199110}
Loading

0 comments on commit ef10317

Please sign in to comment.