Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ lazy val root = project
scalacOptions ++= List(
"-deprecation",
"-feature",
"-unchecked"
"-unchecked",
"-Wunused:all"
),
libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test
)
32 changes: 14 additions & 18 deletions src/main/scala/io/github/acl4s/LazySegtree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import scala.reflect.ClassTag

import io.github.acl4s.internal.{ceilPow2, rightOpenInterval}

final case class LazySegtree[S: Monoid, F](
n: Int,
size: Int,
log: Int,
d: Array[S],
lz: Array[F]
)(using m: MapMonoid[S, F]) {
final case class LazySegtree[S, F](
n: Int
)(using m: Monoid[S], mm: MapMonoid[S, F], tagS: ClassTag[S], tagF: ClassTag[F]) {
val log: Int = ceilPow2(n)
val size: Int = 1 << log
val d: Array[S] = Array.fill(2 * size)(m.e())
val lz: Array[F] = Array.fill(size)(mm.id())

private val _1_to_log = 1 to log
private val _1_to_log_rev = _1_to_log.reverse
Expand All @@ -20,16 +20,16 @@ final case class LazySegtree[S: Monoid, F](
}

private def applyAll(k: Int, f: F): Unit = {
d(k) = m.mapping(f, d(k))
d(k) = mm.mapping(f, d(k))
if (k < size) {
lz(k) = m.composition(f, lz(k))
lz(k) = mm.composition(f, lz(k))
}
}

private def push(k: Int): Unit = {
applyAll(2 * k, lz(k))
applyAll(2 * k + 1, lz(k))
lz(k) = m.id()
lz(k) = mm.id()
}

def set(index: Int, x: S): Unit = {
Expand Down Expand Up @@ -84,7 +84,7 @@ final case class LazySegtree[S: Monoid, F](
assert(0 <= index && index < n)
val p = index + size
_1_to_log_rev.foreach(i => { push(p >> i) })
d(p) = m.mapping(f, d(p))
d(p) = mm.mapping(f, d(p))
_1_to_log.foreach(i => { update(p >> i) })
}

Expand Down Expand Up @@ -192,15 +192,11 @@ final case class LazySegtree[S: Monoid, F](

object LazySegtree {

def apply[S: Monoid, F](n: Int)(using m: MapMonoid[S, F], tagS: ClassTag[S], tagF: ClassTag[F]): LazySegtree[S, F] = {
val log = ceilPow2(n)
val size = 1 << log
val d = Array.fill(2 * size)(m.e())
val lz = Array.fill(size)(m.id())
new LazySegtree(n, size, log, d, lz)
def apply[S, F](n: Int)(using Monoid[S], MapMonoid[S, F], ClassTag[S], ClassTag[F]): LazySegtree[S, F] = {
new LazySegtree(n)
}

def apply[S: Monoid, F](array: Array[S])(using MapMonoid[S, F], ClassTag[S], ClassTag[F]): LazySegtree[S, F] = {
def apply[S, F](array: Array[S])(using Monoid[S], MapMonoid[S, F], ClassTag[S], ClassTag[F]): LazySegtree[S, F] = {
val ret = LazySegtree(array.length)
(0 until ret.n).foreach(i => { ret.d(ret.size + i) = array(i) })
(1 until ret.size).reverse.foreach(ret.update)
Expand Down
3 changes: 0 additions & 3 deletions src/main/scala/io/github/acl4s/MapMonoid.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package io.github.acl4s

trait MapMonoid[S: Monoid, F] {
def e(): S = Monoid[S].e()
def combine(a: S, b: S): S = Monoid[S].combine(a, b)

def id(): F
def mapping(f: F, s: S): S
def composition(a: F, b: F): F
Expand Down
8 changes: 3 additions & 5 deletions src/test/scala/io/github/acl4s/LazySegtreeSuite.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.github.acl4s

import io.github.acl4s.{LazySegtree, MapMonoid, Monoid}

class LazySegtreeSuite extends munit.FunSuite {

/**
Expand All @@ -23,13 +21,13 @@ class LazySegtreeSuite extends munit.FunSuite {
}

given m: MapMonoid[S, Pair[Int]] with {
def id(): Pair[Int] = Pair(1, 0)
def mapping(f: Pair[Int], s: S): S = {
final override def id(): Pair[Int] = Pair(1, 0)
final override def mapping(f: Pair[Int], s: S): S = {
val Pair(b, c) = f
s.a = ((s.a.toLong * b.toLong + s.size.toLong * c.toLong) % MOD).toInt
s
}
def composition(l: Pair[Int], r: Pair[Int]): Pair[Int] = {
final override def composition(l: Pair[Int], r: Pair[Int]): Pair[Int] = {
Pair(
((l.b.toLong * r.b.toLong) % MOD).toInt,
((l.b.toLong * r.c.toLong + l.c.toLong) % MOD).toInt
Expand Down
2 changes: 0 additions & 2 deletions src/test/scala/io/github/acl4s/SegtreeSuite.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.github.acl4s

import io.github.acl4s.{Monoid, Segtree}

class SegtreeSuite extends munit.FunSuite {

/**
Expand Down