Skip to content

Implement Lazy Segtree #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0e8242f
Initial commit for segtree
TonalidadeHidrica Sep 11, 2020
452f9f1
Added segtree
TonalidadeHidrica Sep 11, 2020
c35995e
Removed newline
TonalidadeHidrica Sep 11, 2020
831c35a
Fixed mistakes
TonalidadeHidrica Sep 11, 2020
475676f
Merge branch 'master' into feature/segtree
TonalidadeHidrica Sep 11, 2020
db3e57f
Change identity from constant to function
TonalidadeHidrica Sep 11, 2020
7f70828
Added "Max" monoid and a test
TonalidadeHidrica Sep 11, 2020
dc64b31
Merge branch 'master' into feature/segtree
TonalidadeHidrica Sep 11, 2020
b27d10d
Added sample for J - Segment Tree
TonalidadeHidrica Sep 11, 2020
167cee8
cargo fmt
TonalidadeHidrica Sep 11, 2020
6a6259f
Fixed Default implementation
TonalidadeHidrica Sep 12, 2020
dc1c6b7
Changed Copy to Clone
TonalidadeHidrica Sep 12, 2020
ded9a93
Added LazySegTree
TonalidadeHidrica Sep 12, 2020
3474460
Make MapMonoid underlying type Clone
TonalidadeHidrica Sep 12, 2020
a8b2cb6
Fix a mistake
TonalidadeHidrica Sep 12, 2020
e6ac534
Renamme test function
TonalidadeHidrica Sep 12, 2020
61cd506
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 12, 2020
336bf18
Added a test
TonalidadeHidrica Sep 12, 2020
93a2906
Follow naming convension (mod test -> tests)
TonalidadeHidrica Sep 12, 2020
da2c826
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 12, 2020
51dd0db
Implement Debug for LazySegtree
TonalidadeHidrica Sep 12, 2020
4878021
Added example for Practice2-K
TonalidadeHidrica Sep 12, 2020
707b56d
Added example for Practice2-L
TonalidadeHidrica Sep 12, 2020
3a43da6
Change position of newline
TonalidadeHidrica Sep 12, 2020
14ed754
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 12, 2020
2e3b0be
Merge branch 'master' into feature/segtree
TonalidadeHidrica Sep 13, 2020
c6a6d2c
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 13, 2020
ce40d2a
Apply the change that I forgot
TonalidadeHidrica Sep 13, 2020
4c4516f
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 13, 2020
d51a67b
Split integral traits into four subtraits
TonalidadeHidrica Sep 14, 2020
5650b88
Modify binary_operation and add some traits
TonalidadeHidrica Sep 14, 2020
32dbc68
cargo fmt
TonalidadeHidrica Sep 14, 2020
558a652
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 14, 2020
f54acaf
Change arguments from value to reference
TonalidadeHidrica Sep 14, 2020
48ceeb6
Changed the signature of f in max_right & min_left
TonalidadeHidrica Sep 14, 2020
d4bb776
Changed the monoid namme
TonalidadeHidrica Sep 15, 2020
331ea67
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 15, 2020
ed778ef
Merge branch 'master' into feature/segtree
TonalidadeHidrica Sep 15, 2020
fb9e6c7
Merge branch 'feature/segtree' into feature/lazysegtree
TonalidadeHidrica Sep 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions examples/practice2_j_segment_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use ac_library_rs::{Max, Segtree};
use std::io::Read;

fn main() {
let mut buf = String::new();
std::io::stdin().read_to_string(&mut buf).unwrap();
let mut input = buf.split_whitespace();

let n: usize = input.next().unwrap().parse().unwrap();
let q: usize = input.next().unwrap().parse().unwrap();
let mut segtree = Segtree::<Max<i32>>::new(n + 1);
for i in 1..=n {
segtree.set(i, input.next().unwrap().parse().unwrap());
}
for _ in 0..q {
match input.next().unwrap().parse().unwrap() {
1 => {
let x = input.next().unwrap().parse().unwrap();
let v = input.next().unwrap().parse().unwrap();
segtree.set(x, v);
}
2 => {
let l = input.next().unwrap().parse().unwrap();
let r: usize = input.next().unwrap().parse().unwrap();
println!("{}", segtree.prod(l, r + 1));
}
3 => {
let x = input.next().unwrap().parse().unwrap();
let v = input.next().unwrap().parse().unwrap();
println!("{}", segtree.max_right(x, |a| a < &v))
}
_ => {}
}
}
}
67 changes: 67 additions & 0 deletions examples/practice2_k_range_affine_range_sum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use ac_library_rs::{LazySegtree, MapMonoid, ModInt998244353, Monoid};
use std::io::Read;

type Mint = ModInt998244353;
struct Sum;
impl Monoid for Sum {
type S = (Mint, usize);

fn identity() -> Self::S {
(0.into(), 0)
}

fn binary_operation(&(a, n): &Self::S, &(b, m): &Self::S) -> Self::S {
(a + b, n + m)
}
}
struct Affine;
impl MapMonoid for Affine {
type M = Sum;
type F = (Mint, Mint);

fn identity_map() -> Self::F {
(1.into(), 0.into())
}

fn mapping(&(a, b): &Self::F, &(x, n): &<Self::M as Monoid>::S) -> <Self::M as Monoid>::S {
(a * x + b * Mint::new(n), n)
}

// a(cx + d) + b = (ac)x + (ad+b)
fn composition(&(a, b): &Self::F, &(c, d): &Self::F) -> Self::F {
(a * c, a * d + b)
}
}

#[allow(clippy::many_single_char_names)]
fn main() {
let mut buf = String::new();
std::io::stdin().read_to_string(&mut buf).unwrap();
let mut input = buf.split_whitespace();

let n = input.next().unwrap().parse().unwrap();
let q = input.next().unwrap().parse().unwrap();
let mut segtree: LazySegtree<Affine> = input
.by_ref()
.take(n)
.map(|s| (s.parse().unwrap(), 1))
.collect::<Vec<_>>()
.into();
for _ in 0..q {
match input.next().unwrap().parse().unwrap() {
0 => {
let l = input.next().unwrap().parse().unwrap();
let r = input.next().unwrap().parse().unwrap();
let b = input.next().unwrap().parse().unwrap();
let c = input.next().unwrap().parse().unwrap();
segtree.apply_range(l, r, (b, c));
}
1 => {
let l = input.next().unwrap().parse().unwrap();
let r = input.next().unwrap().parse().unwrap();
println!("{}", segtree.prod(l, r).0);
}
_ => {}
}
}
}
63 changes: 63 additions & 0 deletions examples/practice2_l_lazy_segment_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#![allow(clippy::many_single_char_names)]
use ac_library_rs::{LazySegtree, MapMonoid, Monoid};
use std::io::Read;
use std::iter;

struct M;
impl Monoid for M {
type S = (u64, u64, u64);
fn identity() -> Self::S {
(0, 0, 0)
}
fn binary_operation(&(a, b, c): &Self::S, &(d, e, f): &Self::S) -> Self::S {
(a + d, b + e, c + f + b * d)
}
}
struct F;
impl MapMonoid for F {
type M = M;
type F = bool;

fn identity_map() -> Self::F {
false
}
fn mapping(&f: &Self::F, &(a, b, c): &<M as Monoid>::S) -> <M as Monoid>::S {
if f {
// (a + b) * (a + b - 1) / 2 - a * (a - 1) / 2 - b * (b - 1) / 2 - c
// = a * b - c
(b, a, a * b - c)
} else {
(a, b, c)
}
}
fn composition(&f: &Self::F, &g: &Self::F) -> Self::F {
f ^ g
}
}

fn main() {
let mut buf = String::new();
std::io::stdin().read_to_string(&mut buf).unwrap();
let mut input = buf.split_whitespace();

let n = input.next().unwrap().parse().unwrap();
let q = input.next().unwrap().parse().unwrap();
let mut segtree: LazySegtree<F> = iter::once((0, 0, 0))
.chain(input.by_ref().take(n).map(|s| match s {
"0" => (1, 0, 0),
"1" => (0, 1, 0),
_ => panic!(),
}))
.collect::<Vec<_>>()
.into();
for _ in 0..q {
let t = input.next().unwrap().parse().unwrap();
let l = input.next().unwrap().parse().unwrap();
let r: usize = input.next().unwrap().parse().unwrap();
match t {
1 => segtree.apply_range(l, r + 1, true),
2 => println!("{}", segtree.prod(l, r + 1).2),
_ => {}
}
}
}
30 changes: 29 additions & 1 deletion src/internal_type_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,37 +52,65 @@ pub trait Integral:
+ fmt::Debug
+ fmt::Binary
+ fmt::Octal
+ Zero
+ One
+ BoundedBelow
+ BoundedAbove
{
}

/// Class that has additive identity element
pub trait Zero {
/// The additive identity element
fn zero() -> Self;
}

/// Class that has multiplicative identity element
pub trait One {
/// The multiplicative identity element
fn one() -> Self;
}

pub trait BoundedBelow {
fn min_value() -> Self;
}

pub trait BoundedAbove {
fn max_value() -> Self;
}

macro_rules! impl_integral {
($($ty:ty),*) => {
$(
impl Integral for $ty {
impl Zero for $ty {
#[inline]
fn zero() -> Self {
0
}
}

impl One for $ty {
#[inline]
fn one() -> Self {
1
}
}

impl BoundedBelow for $ty {
#[inline]
fn min_value() -> Self {
Self::min_value()
}
}

impl BoundedAbove for $ty {
#[inline]
fn max_value() -> Self {
Self::max_value()
}
}

impl Integral for $ty {}
)*
};
}
Expand Down
Loading