diff --git a/src/main/scala/io/github/acl4s/FenwickTree.scala b/src/main/scala/io/github/acl4s/FenwickTree.scala index b9171ef..a5f10ef 100644 --- a/src/main/scala/io/github/acl4s/FenwickTree.scala +++ b/src/main/scala/io/github/acl4s/FenwickTree.scala @@ -2,7 +2,7 @@ package io.github.acl4s import scala.reflect.ClassTag -import io.github.acl4s.internal.rightOpenInterval +import io.github.acl4s.internal.{rightOpenInterval, IPair} /** * Reference: https://en.wikipedia.org/wiki/Fenwick_tree @@ -34,7 +34,7 @@ case class FenwickTree[T: ClassTag](n: Int)(using m: AddSub[T]) { } def sum(range: Range): T = { - val (l, r) = rightOpenInterval(range) + val IPair(l, r) = rightOpenInterval(range) sum(l, r) } diff --git a/src/main/scala/io/github/acl4s/LazySegtree.scala b/src/main/scala/io/github/acl4s/LazySegtree.scala index 559e834..09650e5 100644 --- a/src/main/scala/io/github/acl4s/LazySegtree.scala +++ b/src/main/scala/io/github/acl4s/LazySegtree.scala @@ -2,7 +2,7 @@ package io.github.acl4s import scala.reflect.ClassTag -import io.github.acl4s.internal.{ceilPow2, rightOpenInterval} +import io.github.acl4s.internal.{ceilPow2, rightOpenInterval, IPair} final case class LazySegtree[S, F]( n: Int @@ -48,7 +48,7 @@ final case class LazySegtree[S, F]( } def prod(range: Range): S = { - val (l, r) = rightOpenInterval(range) + val IPair(l, r) = rightOpenInterval(range) prod(l, r) } @@ -89,7 +89,7 @@ final case class LazySegtree[S, F]( } def applyRange(range: Range, f: F): Unit = { - val (l, r) = rightOpenInterval(range) + val IPair(l, r) = rightOpenInterval(range) applyRange(l, r, f) } diff --git a/src/main/scala/io/github/acl4s/ModInt.scala b/src/main/scala/io/github/acl4s/ModInt.scala index 6756af1..2a1f557 100644 --- a/src/main/scala/io/github/acl4s/ModInt.scala +++ b/src/main/scala/io/github/acl4s/ModInt.scala @@ -4,13 +4,15 @@ import scala.annotation.targetName import io.github.acl4s.internal.{Barrett, LPair} -private[acl4s] inline def applyIntImpl(value: Int, mod: Int): Long = { - applyLongImpl(value.toLong, mod) +private[acl4s] inline def applyIntImpl(value: Int, mod: Int): Int = { + var x = value % mod + if (x < 0) { x += mod } + x } private[acl4s] inline def applyLongImpl(value: Long, mod: Int): Long = { - var x = value % mod.toLong - if (x < 0L) { x += mod.toLong } + var x = value % mod + if (x < 0L) { x += mod } x } @@ -174,7 +176,7 @@ object StaticModInt { def apply[T <: Int](value: Int)(using m: Modulus[T]): StaticModInt[T] = { val x = applyIntImpl(value, m.value) - new StaticModInt(x.toInt) + new StaticModInt(x) } def apply[T <: Int](value: Long)(using m: Modulus[T]): StaticModInt[T] = { @@ -285,7 +287,7 @@ object DynamicModInt { def apply(value: Int): DynamicModInt = { val x = applyIntImpl(value, bt.m) - new DynamicModInt(x.toInt) + new DynamicModInt(x) } def apply(value: Long): DynamicModInt = { diff --git a/src/main/scala/io/github/acl4s/Segtree.scala b/src/main/scala/io/github/acl4s/Segtree.scala index 61956a4..1f34e96 100644 --- a/src/main/scala/io/github/acl4s/Segtree.scala +++ b/src/main/scala/io/github/acl4s/Segtree.scala @@ -2,7 +2,7 @@ package io.github.acl4s import scala.reflect.ClassTag -import io.github.acl4s.internal.{ceilPow2, rightOpenInterval} +import io.github.acl4s.internal.{ceilPow2, rightOpenInterval, IPair} final case class Segtree[T]( n: Int @@ -30,7 +30,7 @@ final case class Segtree[T]( } def prod(range: Range): T = { - val (l, r) = rightOpenInterval(range) + val IPair(l, r) = rightOpenInterval(range) prod(l, r) } diff --git a/src/main/scala/io/github/acl4s/internal/Range.scala b/src/main/scala/io/github/acl4s/internal/Range.scala index d46b076..0163faf 100644 --- a/src/main/scala/io/github/acl4s/internal/Range.scala +++ b/src/main/scala/io/github/acl4s/internal/Range.scala @@ -1,12 +1,12 @@ package io.github.acl4s.internal -private[acl4s] def rightOpenInterval(range: Range): (Int, Int) = { +private[acl4s] def rightOpenInterval(range: Range): IPair = { assert(range.step == 1 || range.step == -1) if (range.isEmpty) { - (range.start, range.start) + IPair(range.start, range.start) } else if (range.step > 0) { - (range.start, range.last + 1) + IPair(range.start, range.last + 1) } else { - (range.last, range.start + 1) + IPair(range.last, range.start + 1) } } diff --git a/src/main/scala/io/github/acl4s/internal/Tuple.scala b/src/main/scala/io/github/acl4s/internal/Tuple.scala index 47556fe..a0bafbc 100644 --- a/src/main/scala/io/github/acl4s/internal/Tuple.scala +++ b/src/main/scala/io/github/acl4s/internal/Tuple.scala @@ -1,3 +1,4 @@ package io.github.acl4s.internal +final case class IPair(a: Int, b: Int) final case class LPair(a: Long, b: Long) diff --git a/src/test/scala/io/github/acl4s/internal/RangeSuite.scala b/src/test/scala/io/github/acl4s/internal/RangeSuite.scala index b00c2fb..dd87fff 100644 --- a/src/test/scala/io/github/acl4s/internal/RangeSuite.scala +++ b/src/test/scala/io/github/acl4s/internal/RangeSuite.scala @@ -3,17 +3,17 @@ package io.github.acl4s.internal class RangeSuite extends munit.FunSuite { test("rightOpenInterval()") { - assertEquals(rightOpenInterval(0 to 10), (0, 11)) - assertEquals(rightOpenInterval((0 to 10).reverse), (0, 11)) - assertEquals(rightOpenInterval(10 to 0 by -1), (0, 11)) + assertEquals(rightOpenInterval(0 to 10), IPair(0, 11)) + assertEquals(rightOpenInterval((0 to 10).reverse), IPair(0, 11)) + assertEquals(rightOpenInterval(10 to 0 by -1), IPair(0, 11)) - assertEquals(rightOpenInterval(0 until 10), (0, 10)) - assertEquals(rightOpenInterval((0 until 10).reverse), (0, 10)) - assertEquals(rightOpenInterval(10 until 0 by -1), (1, 11)) + assertEquals(rightOpenInterval(0 until 10), IPair(0, 10)) + assertEquals(rightOpenInterval((0 until 10).reverse), IPair(0, 10)) + assertEquals(rightOpenInterval(10 until 0 by -1), IPair(1, 11)) - assertEquals(rightOpenInterval(0 to 0), (0, 1)) - assertEquals(rightOpenInterval((0 until 0).reverse), (0, 0)) - assertEquals(rightOpenInterval(0 until 0 by -1), (0, 0)) + assertEquals(rightOpenInterval(0 to 0), IPair(0, 1)) + assertEquals(rightOpenInterval((0 until 0).reverse), IPair(0, 0)) + assertEquals(rightOpenInterval(0 until 0 by -1), IPair(0, 0)) } }