src/nt/sbt/lib.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../util/consts/lib.hpp" | ||
| 4 | #include "../../util/traits/math/lib.hpp" | ||
| 5 | |||
| 6 | namespace tifa_libs { | ||
| 7 | |||
| 8 | template <uint_c T> | ||
| 9 | struct sbt { | ||
| 10 | T x{1}, y{1}; // now | ||
| 11 | T lx{0}, ly{1}; // lbound | ||
| 12 | T rx{1}, ry{0}; // rbound | ||
| 13 | |||
| 14 | CEXP sbt() NE = default; | ||
| 15 | |||
| 16 | 6470889 | CEXP void movl(int_c auto step = 1) NE { | |
| 17 | using W = std::conditional_t<sint_c<decltype(step)>, to_sint_t<decltype(step * x)>, decltype(step * x)>; | ||
| 18 | 6470889 | rx += T((W)lx * step), ry += T((W)ly * step), x = rx + lx, y = ry + ly; | |
| 19 | 6470889 | } | |
| 20 | 6362458 | CEXP void movr(int_c auto step = 1) NE { | |
| 21 | using W = std::conditional_t<sint_c<decltype(step)>, to_sint_t<decltype(step * x)>, decltype(step * x)>; | ||
| 22 | 6362458 | lx += T((W)rx * step), ly += T((W)ry * step), x = rx + lx, y = ry + ly; | |
| 23 | 6362458 | } | |
| 24 | |||
| 25 | // dir: true -> move to rchild; false -> move to lchil | ||
| 26 | template <class F> | ||
| 27 | requires requires(F f, bool dir, T step) { f(dir, step); } | ||
| 28 | 809628 | static CEXP sbt walk_to(T x, T y, F&& f) NE { | |
| 29 | 809628 | sbt sbt; | |
| 30 | 809628 | bool dir = false; | |
| 31 |
6/6tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#1}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#1}&&):
✓ Branch 0 taken 2790971 times.
✓ Branch 1 taken 257204 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#2}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#2}&&):
✓ Branch 0 taken 3908371 times.
✓ Branch 1 taken 295222 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&>(unsigned long, unsigned long, tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&):
✓ Branch 0 taken 2790887 times.
✓ Branch 1 taken 257202 times.
|
10299857 | while (y) { |
| 32 | 9490229 | T step = x / y; | |
| 33 |
6/6tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#1}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#1}&&):
✓ Branch 1 taken 257204 times.
✓ Branch 2 taken 2533767 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#2}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#2}&&):
✓ Branch 1 taken 295222 times.
✓ Branch 2 taken 3613149 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&>(unsigned long, unsigned long, tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&):
✓ Branch 1 taken 257202 times.
✓ Branch 2 taken 2533685 times.
|
9490229 | if (dir = !dir, std::swap(x %= y, y); !y) --step; |
| 34 |
6/6tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#1}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#1}&&):
✓ Branch 0 taken 148203 times.
✓ Branch 1 taken 2642768 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#2}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#2}&&):
✓ Branch 0 taken 165852 times.
✓ Branch 1 taken 3742519 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&>(unsigned long, unsigned long, tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&):
✓ Branch 0 taken 148201 times.
✓ Branch 1 taken 2642686 times.
|
9490229 | if (!step) continue; |
| 35 |
6/6tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#1}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#1}&&):
✓ Branch 1 taken 1311625 times.
✓ Branch 2 taken 1331143 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<main::{lambda(bool, unsigned long)#2}>(unsigned long, unsigned long, main::{lambda(bool, unsigned long)#2}&&):
✓ Branch 1 taken 1862226 times.
✓ Branch 2 taken 1880293 times.
tifa_libs::sbt<unsigned long> tifa_libs::sbt<unsigned long>::walk_to<tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&>(unsigned long, unsigned long, tifa_libs::fn_0::{lambda((auto:1&&)...)#1} const&):
✓ Branch 1 taken 1311584 times.
✓ Branch 2 taken 1331102 times.
|
9027973 | if (f(dir, step); dir) sbt.movr(step); |
| 36 | 4542538 | else sbt.movl(step); | |
| 37 | } | ||
| 38 | 809628 | return sbt; | |
| 39 | } | ||
| 40 | 257202 | static CEXP sbt walk_to(T x, T y) NE { return walk_to(x, y, fn_0); } | |
| 41 | // dir: true -> move to rchild; false -> move to lchil | ||
| 42 | template <class F> | ||
| 43 | requires requires(F f, bool dir, T step) { f(dir, step); } | ||
| 44 | 233699 | static CEXP sbt walk_to_lca(T x1, T y1, T x2, T y2, F&& f) NE { | |
| 45 | 233699 | sbt sbt; | |
| 46 | 233699 | bool dir = false; | |
| 47 |
4/4✓ Branch 0 taken 349611 times.
✓ Branch 1 taken 1382 times.
✓ Branch 2 taken 348871 times.
✓ Branch 3 taken 740 times.
|
350993 | while (y1 && y2) { |
| 48 | 348871 | T step1 = x1 / y1, step2 = x2 / y2; | |
| 49 |
2/2✓ Branch 1 taken 14899 times.
✓ Branch 2 taken 333972 times.
|
348871 | if (dir = !dir, std::swap(x1 %= y1, y1); !y1) --step1; |
| 50 |
2/2✓ Branch 1 taken 14898 times.
✓ Branch 2 taken 333973 times.
|
348871 | if (std::swap(x2 %= y2, y2); !y2) --step2; |
| 51 |
2/2✓ Branch 1 taken 161593 times.
✓ Branch 2 taken 187278 times.
|
348871 | if (T step = min(step1, step2); step) { |
| 52 |
2/2✓ Branch 1 taken 68481 times.
✓ Branch 2 taken 93112 times.
|
161593 | if (f(dir, step); dir) sbt.movr(step); |
| 53 | 93112 | else sbt.movl(step); | |
| 54 | } | ||
| 55 |
2/2✓ Branch 0 taken 231577 times.
✓ Branch 1 taken 117294 times.
|
348871 | if (step1 != step2) break; |
| 56 | } | ||
| 57 | 233699 | return sbt; | |
| 58 | } | ||
| 59 | 233699 | static CEXP sbt walk_to_lca(T x1, T y1, T x2, T y2) NE { return walk_to_lca(x1, y1, x2, y2, fn_0); } | |
| 60 | }; | ||
| 61 | |||
| 62 | } // namespace tifa_libs | ||
| 63 |