use super::functions::*;
#[allow(dead_code)]
pub struct CircularBuffer {
data: Vec<i64>,
head: usize,
tail: usize,
len: usize,
cap: usize,
}
#[allow(dead_code)]
impl CircularBuffer {
pub fn new(cap: usize) -> Self {
CircularBuffer {
data: vec![0; cap],
head: 0,
tail: 0,
len: 0,
cap,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn is_full(&self) -> bool {
self.len == self.cap
}
pub fn push_back(&mut self, val: i64) -> bool {
if self.is_full() {
return false;
}
self.data[self.tail] = val;
self.tail = (self.tail + 1) % self.cap;
self.len += 1;
true
}
pub fn pop_front(&mut self) -> Option<i64> {
if self.is_empty() {
return None;
}
let val = self.data[self.head];
self.head = (self.head + 1) % self.cap;
self.len -= 1;
Some(val)
}
pub fn front(&self) -> Option<i64> {
if self.is_empty() {
None
} else {
Some(self.data[self.head])
}
}
}
#[allow(dead_code)]
pub struct SparseTable {
table: Vec<Vec<i64>>,
log2: Vec<usize>,
n: usize,
}
#[allow(dead_code)]
impl SparseTable {
pub fn build(data: &[i64]) -> Self {
let n = data.len();
if n == 0 {
return SparseTable {
table: vec![],
log2: vec![],
n: 0,
};
}
let mut log2 = vec![0usize; n + 1];
for i in 2..=n {
log2[i] = log2[i / 2] + 1;
}
let k = log2[n] + 1;
let mut table = vec![vec![i64::MAX; n]; k];
table[0][..n].copy_from_slice(data);
for j in 1..k {
for i in 0..=n.saturating_sub(1 << j) {
table[j][i] = table[j - 1][i].min(table[j - 1][i + (1 << (j - 1))]);
}
}
SparseTable { table, log2, n }
}
pub fn query_min(&self, lo: usize, hi: usize) -> i64 {
if lo > hi || hi >= self.n {
return i64::MAX;
}
let j = self.log2[hi - lo + 1];
self.table[j][lo].min(self.table[j][hi + 1 - (1 << j)])
}
}
#[allow(dead_code)]
pub struct DifferenceArray {
diff: Vec<i64>,
}
#[allow(dead_code)]
impl DifferenceArray {
pub fn build(data: &[i64]) -> Self {
let n = data.len();
let mut diff = vec![0i64; n + 1];
if n > 0 {
diff[0] = data[0];
}
for i in 1..n {
diff[i] = data[i] - data[i - 1];
}
DifferenceArray { diff }
}
pub fn range_add(&mut self, lo: usize, hi: usize, val: i64) {
self.diff[lo] += val;
if hi + 1 < self.diff.len() {
self.diff[hi + 1] -= val;
}
}
pub fn reconstruct(&self) -> Vec<i64> {
let n = self.diff.len() - 1;
let mut result = vec![0i64; n];
if n == 0 {
return result;
}
result[0] = self.diff[0];
for i in 1..n {
result[i] = result[i - 1] + self.diff[i];
}
result
}
}
#[allow(dead_code)]
pub struct PrefixSum {
prefix: Vec<i64>,
}
#[allow(dead_code)]
impl PrefixSum {
pub fn build(data: &[i64]) -> Self {
let mut prefix = vec![0i64; data.len() + 1];
for (i, &x) in data.iter().enumerate() {
prefix[i + 1] = prefix[i] + x;
}
PrefixSum { prefix }
}
pub fn range_sum(&self, lo: usize, hi: usize) -> i64 {
self.prefix[hi + 1] - self.prefix[lo]
}
pub fn len(&self) -> usize {
self.prefix.len() - 1
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}