///|
/// Additive identity. Implementations used in Fenwick trees must form an abelian group.
pub(open) trait Zero {
fn zero() -> Self
}
///|
/// Signed capacity/cost types supported by flow algorithms.
pub trait FlowInt {
fn to_i64(Self) -> Int64
fn from_i64(Int64) -> Self
fn maximum() -> Int64
}
///|
/// Lossless modular reduction of the four ACL integer types.
pub trait ModInput {
fn reduce(Self, Int) -> Int
fn from_residue(Int) -> Self
}
///|
pub impl Zero for Int with fn zero() {
0
}
///|
pub impl FlowInt for Int with fn to_i64(self) {
self.to_int64()
}
///|
pub impl FlowInt for Int with fn from_i64(x) {
x.to_int()
}
///|
pub impl FlowInt for Int with fn maximum() {
2147483647L
}
///|
pub impl ModInput for Int with fn reduce(self, m) {
let r = self.to_int64() % m.to_int64()
(if r < 0L { r + m.to_int64() } else { r }).to_int()
}
///|
pub impl ModInput for Int with fn from_residue(x) {
x
}
///|
pub impl Zero for Int64 with fn zero() {
0L
}
///|
pub impl FlowInt for Int64 with fn to_i64(self) {
self
}
///|
pub impl FlowInt for Int64 with fn from_i64(x) {
x
}
///|
pub impl FlowInt for Int64 with fn maximum() {
9223372036854775807L
}
///|
pub impl ModInput for Int64 with fn reduce(self, m) {
let r = self % m.to_int64()
(if r < 0L { r + m.to_int64() } else { r }).to_int()
}
///|
pub impl ModInput for Int64 with fn from_residue(x) {
x.to_int64()
}
///|
pub impl Zero for UInt with fn zero() {
0U
}
///|
pub impl ModInput for UInt with fn reduce(self, m) {
(self.to_uint64() % m.to_uint64()).to_int()
}
///|
pub impl ModInput for UInt with fn from_residue(x) {
x.reinterpret_as_uint()
}
///|
pub impl Zero for UInt64 with fn zero() {
0UL
}
///|
pub impl ModInput for UInt64 with fn reduce(self, m) {
(self % m.to_uint64()).to_int()
}
///|
pub impl ModInput for UInt64 with fn from_residue(x) {
x.to_uint64()
}