Skip to content

Commit c2bb69c

Browse files
authored
Merge pull request #44 from TonalidadeHidrica/feature/lazysegtree
Implement Lazy Segtree
2 parents 319d19b + fb9e6c7 commit c2bb69c

7 files changed

+925
-1
lines changed

examples/practice2_j_segment_tree.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use ac_library_rs::{Max, Segtree};
2+
use std::io::Read;
3+
4+
fn main() {
5+
let mut buf = String::new();
6+
std::io::stdin().read_to_string(&mut buf).unwrap();
7+
let mut input = buf.split_whitespace();
8+
9+
let n: usize = input.next().unwrap().parse().unwrap();
10+
let q: usize = input.next().unwrap().parse().unwrap();
11+
let mut segtree = Segtree::<Max<i32>>::new(n + 1);
12+
for i in 1..=n {
13+
segtree.set(i, input.next().unwrap().parse().unwrap());
14+
}
15+
for _ in 0..q {
16+
match input.next().unwrap().parse().unwrap() {
17+
1 => {
18+
let x = input.next().unwrap().parse().unwrap();
19+
let v = input.next().unwrap().parse().unwrap();
20+
segtree.set(x, v);
21+
}
22+
2 => {
23+
let l = input.next().unwrap().parse().unwrap();
24+
let r: usize = input.next().unwrap().parse().unwrap();
25+
println!("{}", segtree.prod(l, r + 1));
26+
}
27+
3 => {
28+
let x = input.next().unwrap().parse().unwrap();
29+
let v = input.next().unwrap().parse().unwrap();
30+
println!("{}", segtree.max_right(x, |a| a < &v))
31+
}
32+
_ => {}
33+
}
34+
}
35+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use ac_library_rs::{LazySegtree, MapMonoid, ModInt998244353, Monoid};
2+
use std::io::Read;
3+
4+
type Mint = ModInt998244353;
5+
struct Sum;
6+
impl Monoid for Sum {
7+
type S = (Mint, usize);
8+
9+
fn identity() -> Self::S {
10+
(0.into(), 0)
11+
}
12+
13+
fn binary_operation(&(a, n): &Self::S, &(b, m): &Self::S) -> Self::S {
14+
(a + b, n + m)
15+
}
16+
}
17+
struct Affine;
18+
impl MapMonoid for Affine {
19+
type M = Sum;
20+
type F = (Mint, Mint);
21+
22+
fn identity_map() -> Self::F {
23+
(1.into(), 0.into())
24+
}
25+
26+
fn mapping(&(a, b): &Self::F, &(x, n): &<Self::M as Monoid>::S) -> <Self::M as Monoid>::S {
27+
(a * x + b * Mint::new(n), n)
28+
}
29+
30+
// a(cx + d) + b = (ac)x + (ad+b)
31+
fn composition(&(a, b): &Self::F, &(c, d): &Self::F) -> Self::F {
32+
(a * c, a * d + b)
33+
}
34+
}
35+
36+
#[allow(clippy::many_single_char_names)]
37+
fn main() {
38+
let mut buf = String::new();
39+
std::io::stdin().read_to_string(&mut buf).unwrap();
40+
let mut input = buf.split_whitespace();
41+
42+
let n = input.next().unwrap().parse().unwrap();
43+
let q = input.next().unwrap().parse().unwrap();
44+
let mut segtree: LazySegtree<Affine> = input
45+
.by_ref()
46+
.take(n)
47+
.map(|s| (s.parse().unwrap(), 1))
48+
.collect::<Vec<_>>()
49+
.into();
50+
for _ in 0..q {
51+
match input.next().unwrap().parse().unwrap() {
52+
0 => {
53+
let l = input.next().unwrap().parse().unwrap();
54+
let r = input.next().unwrap().parse().unwrap();
55+
let b = input.next().unwrap().parse().unwrap();
56+
let c = input.next().unwrap().parse().unwrap();
57+
segtree.apply_range(l, r, (b, c));
58+
}
59+
1 => {
60+
let l = input.next().unwrap().parse().unwrap();
61+
let r = input.next().unwrap().parse().unwrap();
62+
println!("{}", segtree.prod(l, r).0);
63+
}
64+
_ => {}
65+
}
66+
}
67+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#![allow(clippy::many_single_char_names)]
2+
use ac_library_rs::{LazySegtree, MapMonoid, Monoid};
3+
use std::io::Read;
4+
use std::iter;
5+
6+
struct M;
7+
impl Monoid for M {
8+
type S = (u64, u64, u64);
9+
fn identity() -> Self::S {
10+
(0, 0, 0)
11+
}
12+
fn binary_operation(&(a, b, c): &Self::S, &(d, e, f): &Self::S) -> Self::S {
13+
(a + d, b + e, c + f + b * d)
14+
}
15+
}
16+
struct F;
17+
impl MapMonoid for F {
18+
type M = M;
19+
type F = bool;
20+
21+
fn identity_map() -> Self::F {
22+
false
23+
}
24+
fn mapping(&f: &Self::F, &(a, b, c): &<M as Monoid>::S) -> <M as Monoid>::S {
25+
if f {
26+
// (a + b) * (a + b - 1) / 2 - a * (a - 1) / 2 - b * (b - 1) / 2 - c
27+
// = a * b - c
28+
(b, a, a * b - c)
29+
} else {
30+
(a, b, c)
31+
}
32+
}
33+
fn composition(&f: &Self::F, &g: &Self::F) -> Self::F {
34+
f ^ g
35+
}
36+
}
37+
38+
fn main() {
39+
let mut buf = String::new();
40+
std::io::stdin().read_to_string(&mut buf).unwrap();
41+
let mut input = buf.split_whitespace();
42+
43+
let n = input.next().unwrap().parse().unwrap();
44+
let q = input.next().unwrap().parse().unwrap();
45+
let mut segtree: LazySegtree<F> = iter::once((0, 0, 0))
46+
.chain(input.by_ref().take(n).map(|s| match s {
47+
"0" => (1, 0, 0),
48+
"1" => (0, 1, 0),
49+
_ => panic!(),
50+
}))
51+
.collect::<Vec<_>>()
52+
.into();
53+
for _ in 0..q {
54+
let t = input.next().unwrap().parse().unwrap();
55+
let l = input.next().unwrap().parse().unwrap();
56+
let r: usize = input.next().unwrap().parse().unwrap();
57+
match t {
58+
1 => segtree.apply_range(l, r + 1, true),
59+
2 => println!("{}", segtree.prod(l, r + 1).2),
60+
_ => {}
61+
}
62+
}
63+
}

src/internal_type_traits.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,37 +52,65 @@ pub trait Integral:
5252
+ fmt::Debug
5353
+ fmt::Binary
5454
+ fmt::Octal
55+
+ Zero
56+
+ One
57+
+ BoundedBelow
58+
+ BoundedAbove
5559
{
60+
}
61+
62+
/// Class that has additive identity element
63+
pub trait Zero {
64+
/// The additive identity element
5665
fn zero() -> Self;
66+
}
67+
68+
/// Class that has multiplicative identity element
69+
pub trait One {
70+
/// The multiplicative identity element
5771
fn one() -> Self;
72+
}
73+
74+
pub trait BoundedBelow {
5875
fn min_value() -> Self;
76+
}
77+
78+
pub trait BoundedAbove {
5979
fn max_value() -> Self;
6080
}
6181

6282
macro_rules! impl_integral {
6383
($($ty:ty),*) => {
6484
$(
65-
impl Integral for $ty {
85+
impl Zero for $ty {
6686
#[inline]
6787
fn zero() -> Self {
6888
0
6989
}
90+
}
7091

92+
impl One for $ty {
7193
#[inline]
7294
fn one() -> Self {
7395
1
7496
}
97+
}
7598

99+
impl BoundedBelow for $ty {
76100
#[inline]
77101
fn min_value() -> Self {
78102
Self::min_value()
79103
}
104+
}
80105

106+
impl BoundedAbove for $ty {
81107
#[inline]
82108
fn max_value() -> Self {
83109
Self::max_value()
84110
}
85111
}
112+
113+
impl Integral for $ty {}
86114
)*
87115
};
88116
}

0 commit comments

Comments
 (0)