This documentation is automatically generated by online-judge-tools/verification-helper
require "spec" require "../../src/math/mint" require "../../atcoder/src/Math" private MOD1 = 1000000007i64 private MOD2 = 998244353i64 private macro check_binary_operator(type, op) %mod = {{type}}.mod 0i64.step(to: %mod, by: %mod // 1000).each do |x| 0i64.step(to: %mod, by: %mod // 999).each do |y| m = {{type}}.new(x) {{op.id}} {{type}}.new(y) expect = (x {{op.id}} y) % %mod m.should eq expect end end end private macro check_method(type, method) %mod = {{type}}.mod 0i64.step(to: %mod, by: %mod // 1000000).each do |x| {{type}}.new(x).{{method}}.should eq x.{{method}} end end private macro check_method_mod(type, method) %mod = {{type}}.mod 0i64.step(to: %mod, by: %mod // 1000000).each do |x| {{type}}.new(x).{{method}}.should eq x.{{method}} % %mod end end describe "Mint" do it ".[]" do Mint[0, 1, 2, 3, MOD1, MOD1 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint)) Mint2[0, 1, 2, 3, MOD2, MOD2 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint2)) Mint[0, 1, MOD1, MOD1 + 1, MOD1 * 2].map(&.value).should eq [0, 1, 0, 1, 0] end it ".mod" do Mint.mod.should eq MOD1 ModInt(42).mod.should eq 42 end it ".zero" do Mint.zero.should eq 0 end it "#initialize" do Mint.new.should eq 0 Mint.new(Int64::MIN).should eq Int64::MIN % MOD1 Mint.new(0).should eq 0 Mint.new(42).should eq 42 Mint.new(42i64).should eq 42 Mint.new(42i8).should eq 42 Mint.new(MOD1).should eq 0 Mint.new(MOD1 + 1).should eq 1 Mint.new(MOD1 * MOD1).should eq 0 Mint.new(Int64::MAX).should eq Int64::MAX % MOD1 end it "#+" do (+Mint.new).should eq 0 (+Mint.new(12)).should eq 12 end it "#-" do (-Mint.new).should eq 0 (-Mint.new(12)).should eq MOD1 - 12 end it "#+(other)" do a, b = Mint.new(1), Mint.new(-1) (a + a).should eq 2 (a + 3).should eq 4 (a + 3i64).should eq 4 (a + 3i8).should eq 4 (a + MOD1).should eq 1 (a + MOD1 * 2).should eq 1 (b + b).should eq MOD1 - 2 check_binary_operator(Mint, :+) check_binary_operator(Mint2, :+) end it "#-(other)" do a, b = Mint.new(3), Mint.new(-1) (a - Mint.new(4)).should eq MOD1 - 1 (a - 3).should eq 0 (a - 3i64).should eq 0 (a - 3i8).should eq 0 (a - 4).should eq MOD1 - 1 (a - MOD1).should eq 3 (Mint.zero - b).should eq 1 check_binary_operator(Mint, :-) check_binary_operator(Mint2, :-) end it "#*(other)" do a, b = Mint.new(3), Mint.new(-1) (a * 3).should eq 9 (a * a).should eq 9 (a * MOD1).should eq 0 (b * MOD1).should eq 0 (b * b).should eq 1 (b * Int64::MAX).should eq MOD1.pred * (Int64::MAX % MOD1) % MOD1 check_binary_operator(Mint, :*) check_binary_operator(Mint2, :*) end it "#/(other)" do a = Mint.new(3) (a / 1).should eq 3 (a / 2).should eq MOD1 // 2 + 2 (a / 3).should eq 1 {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000) do |x| 0i64.step(by: %mod, to: %mod // 999) do |y| next unless y.gcd(%mod) == 1 z = {{type}}.new(x) / y (z * y).should eq x end end {% end %} expect_raises(DivisionByZeroError) { a / 0 } expect_raises(DivisionByZeroError) { a / 0i8 } expect_raises(DivisionByZeroError) { a / MOD1 } expect_raises(DivisionByZeroError) { a / Mint.zero } end it "#//(other)" do a = Mint.new(3) (a // 1).should eq 3 (a // 2).should eq MOD1 // 2 + 2 (a // 3).should eq 1 {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000) do |x| 0i64.step(by: %mod, to: %mod // 999) do |y| next unless y.gcd(%mod) == 1 z = {{type}}.new(x) // y (z * y).should eq x end end {% end %} expect_raises(DivisionByZeroError) { a // 0 } expect_raises(DivisionByZeroError) { a // 0i8 } expect_raises(DivisionByZeroError) { a // MOD1 } expect_raises(DivisionByZeroError) { a // Mint.zero } end it "#**(other)" do a = Mint.new(3) (a ** 0).should eq 1 (a ** 1).should eq 3 (a ** 2).should eq 9 (a ** 20).should eq 486784380 (a ** (10i64**18)).should eq 246336683 (a.pred ** (10i64**18)).should eq 719476260 {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000) do |x| 0i64.step(by: Int64::MAX, to: Int64::MAX // 1000) do |e| m = {{type}}.new(x) ** e expect = AtCoder::Math.pow_mod(x, e, %mod) m.should eq expect end end {% end %} end it "#inv" do {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000000) do |x| next unless x.gcd(%mod) == 1 ({{type}}.new(x).inv * x).should eq 1 end {% end %} end it "#==(other)" do a = Mint.new(3) (a == a).should be_true (a == 3).should be_true (a == MOD1 + 3).should be_false (a == Mint.new(MOD1 + 3)).should be_true end it "#!=(other)" do a = Mint.new(3) (a != a).should be_false (a != MOD1 + 3).should be_true (a != Mint.new(MOD1 + 3)).should be_false end it "#succ" do Mint.new(0).succ.should eq 1 Mint.new(3).succ.should eq 4 Mint.new(MOD1).succ.should eq 1 Mint.new(-1).succ.should eq 0 check_method_mod(Mint, succ) check_method_mod(Mint2, succ) end it "#pred" do Mint.new(0).pred.should eq MOD1 - 1 Mint.new(3).pred.should eq 2 Mint.new(MOD1).pred.should eq MOD1 - 1 Mint.new(-1).pred.should eq MOD1 - 2 check_method_mod(Mint, pred) check_method_mod(Mint2, pred) end it "#abs" do Mint.new(0).abs.should eq 0 Mint.new(3).abs.should eq 3 Mint.new(MOD1).abs.should eq 0 Mint.new(-1).abs.should eq MOD1 - 1 check_method_mod(Mint, abs) check_method_mod(Mint2, abs) end it "#value" do Mint.new(0).value.should eq 0 Mint.new(3).value.should eq 3 Mint.new(MOD1).value.should eq 0 Mint.new(-1).value.should eq MOD1 - 1 end it "#to_s" do Mint.new(0).to_s.should eq "0" Mint.new(3).to_s.should eq "3" Mint.new(MOD1).to_s.should eq "0" Mint.new(-1).to_s.should eq MOD1.pred.to_s check_method(Mint, to_s) check_method(Mint2, to_s) end it "#inspect" do Mint.new(0).inspect.should eq "0" Mint.new(3).inspect.should eq "3" Mint.new(MOD1).inspect.should eq "0" Mint.new(-1).inspect.should eq (MOD1 - 1).inspect check_method(Mint, inspect) check_method(Mint2, inspect) end end describe Int do it "#to_m" do (-1).to_m(Mint).should eq MOD1 - 1 (-1i8).to_m(Mint).should eq MOD1 - 1 0.to_m(Mint).should eq 0 1i64.to_m(Mint).should eq 1 MOD1.to_m(Mint).should eq 0 (-1).to_m(Mint2).should eq MOD2 - 1 end end describe String do it "#to_m" do "-1".to_m(Mint).should eq MOD1 - 1 "0".to_m(Mint).should eq 0 "1".to_m(Mint).should eq 1 MOD1.pred.to_s.to_m(Mint).should eq MOD1 - 1 MOD1.to_s.to_m(Mint).should eq 0 "-1".to_m(Mint2).should eq MOD2 - 1 end end
require "spec" # require "../../src/math/mint" struct ModInt(MOD) def self.mod MOD end def self.zero new end def self.raw(value : Int64) result = new result.value = value result end macro [](*nums) Array({{@type}}).build({{nums.size}}) do |buffer| {% for num, i in nums %} buffer[{{i}}] = {{@type}}.new({{num}}) {% end %} {{nums.size}} end end getter value : Int64 private macro check_mod {% if MOD.is_a?(NumberLiteral) %} {% raise "can't instantiate ModInt(MOD) with MOD = #{MOD} (MOD must be positive)" unless MOD >= 1 %} {% raise "can't instantiate ModInt(MOD) with MOD = #{MOD.kind} (MOD must be Int64)" unless MOD.kind == :i64 %} {% else %} {% raise "can't instantiate ModInt(MOD) with MOD = #{MOD.class_name.id} (MOD must be an integer)" %} {% end %} end def initialize check_mod @value = 0i64 end def initialize(value) check_mod @value = value.to_i64 % MOD end def initialize(m : ModInt(MOD2)) forall MOD2 {% raise "Can't create ModInt(#{MOD}) from ModInt(#{MOD2})" if MOD != MOD2 %} check_mod @value = m.value end protected def value=(value : Int64) @value = value end def self.scan(scanner, io : IO) : self new scanner.i64(io) end def ==(m : ModInt(MOD2)) forall MOD2 {% raise "Can't compare ModInt(#{MOD}) and ModInt(#{MOD2})" if MOD != MOD2 %} value == m.value end def ==(m : Int) value == m end def + : self self end def - : self self.class.raw(value != 0 ? MOD &- value : 0i64) end def +(v) self + self.class.new(v) end def +(m : self) x = value &+ m.value x &-= MOD if x >= MOD self.class.raw(x) end def -(v) self - self.class.new(v) end def -(m : self) x = value &- m.value x &+= MOD if x < 0 self.class.raw(x) end def *(v) self * self.class.new(v) end def *(m : self) self.class.new(value &* m.value) end def /(v) self / self.class.new(v) end def /(m : self) raise DivisionByZeroError.new if m.value == 0 a, b, u, v = m.value, MOD, 1i64, 0i64 while b != 0 t = a // b a &-= t &* b a, b = b, a u &-= t &* v u, v = v, u end self.class.new(value &* u) end def //(v) self / v end def **(exponent : Int) t, res = self, self.class.raw(1i64) while exponent > 0 res *= t if exponent & 1 == 1 t *= t exponent >>= 1 end res end {% for op in %w[< <= > >=] %} def {{op.id}}(other) raise NotImplementedError.new({{op}}) end {% end %} def inv self.class.raw(1) // self end def succ self.class.raw(value != MOD &- 1 ? value &+ 1 : 0i64) end def pred self.class.raw(value != 0 ? value &- 1 : MOD &- 1) end def abs self end def abs2 self * self end def to_i64 : Int64 value end def to_s(io : IO) : Nil value.to_s(io) end def inspect(io : IO) : Nil value.inspect(io) end end struct Int def to_m(type : M.class) forall M M.new(self) end end class String def to_m(type : M.class) forall M M.new(self) end end alias Mint = ModInt(1000000007i64) alias Mint2 = ModInt(998244353i64) # require "../../atcoder/src/Math" # ac-library.cr by hakatashi https://github.com/google/ac-library.cr # # Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module AtCoder # Implements [ACL's Math library](https://atcoder.github.io/ac-library/master/document_en/math.html) module Math def self.extended_gcd(a, b) last_remainder, remainder = a.abs, b.abs x, last_x, y, last_y = 0_i64, 1_i64, 1_i64, 0_i64 while remainder != 0 new_last_remainder = remainder quotient, remainder = last_remainder.divmod(remainder) last_remainder = new_last_remainder x, last_x = last_x - quotient * x, x y, last_y = last_y - quotient * y, y end return last_remainder, last_x * (a < 0 ? -1 : 1) end # Implements atcoder::inv_mod(value, modulo). def self.inv_mod(value, modulo) gcd, inv = extended_gcd(value, modulo) if gcd != 1 raise ArgumentError.new("#{value} and #{modulo} are not coprime") end inv % modulo end # Simplified AtCoder::Math.pow_mod with support of Int64 def self.pow_mod(base, exponent, modulo) if exponent == 0 return base.class.zero + 1 end if base == 0 return base end b = exponent > 0 ? base : inv_mod(base, modulo) e = exponent.abs ret = 1_i64 while e > 0 if e % 2 == 1 ret = mul_mod(ret, b, modulo) end b = mul_mod(b, b, modulo) e //= 2 end ret end # Caluculates a * b % mod without overflow detection @[AlwaysInline] def self.mul_mod(a : Int64, b : Int64, mod : Int64) if mod < Int32::MAX return a * b % mod end # 31-bit width a_high = (a >> 32).to_u64 # 32-bit width a_low = (a & 0xFFFFFFFF).to_u64 # 31-bit width b_high = (b >> 32).to_u64 # 32-bit width b_low = (b & 0xFFFFFFFF).to_u64 # 31-bit + 32-bit + 1-bit = 64-bit c = a_high * b_low + b_high * a_low c_high = c >> 32 c_low = c & 0xFFFFFFFF # 31-bit + 31-bit res_high = a_high * b_high + c_high # 32-bit + 32-bit res_low = a_low * b_low res_low_high = res_low >> 32 res_low_low = res_low & 0xFFFFFFFF # Overflow if res_low_high + c_low >= 0x100000000 res_high += 1 end res_low = (((res_low_high + c_low) & 0xFFFFFFFF) << 32) | res_low_low (((res_high.to_i128 << 64) | res_low) % mod).to_i64 end @[AlwaysInline] def self.mul_mod(a, b, mod) typeof(mod).new(a.to_i64 * b % mod) end # Implements atcoder::crt(remainders, modulos). def self.crt(remainders, modulos) raise ArgumentError.new unless remainders.size == modulos.size total_modulo = 1_i64 answer = 0_i64 remainders.zip(modulos).each do |(remainder, modulo)| gcd, p = extended_gcd(total_modulo, modulo) if (remainder - answer) % gcd != 0 return 0_i64, 0_i64 end tmp = (remainder - answer) // gcd * p % (modulo // gcd) answer += total_modulo * tmp total_modulo *= modulo // gcd end return answer % total_modulo, total_modulo end # Implements atcoder::floor_sum(n, m, a, b). def self.floor_sum(n, m, a, b) n, m, a, b = n.to_i64, m.to_i64, a.to_i64, b.to_i64 res = 0_i64 if a < 0 a2 = a % m res -= n * (n - 1) // 2 * ((a2 - a) // m) a = a2 end if b < 0 b2 = b % m res -= n * ((b2 - b) // m) b = b2 end res + floor_sum_unsigned(n, m, a, b) end private def self.floor_sum_unsigned(n, m, a, b) res = 0_i64 loop do if a >= m res += n * (n - 1) // 2 * (a // m) a = a % m end if b >= m res += n * (b // m) b = b % m end y_max = a * n + b break if y_max < m n = y_max // m b = y_max % m m, a = a, m end res end end end private MOD1 = 1000000007i64 private MOD2 = 998244353i64 private macro check_binary_operator(type, op) %mod = {{type}}.mod 0i64.step(to: %mod, by: %mod // 1000).each do |x| 0i64.step(to: %mod, by: %mod // 999).each do |y| m = {{type}}.new(x) {{op.id}} {{type}}.new(y) expect = (x {{op.id}} y) % %mod m.should eq expect end end end private macro check_method(type, method) %mod = {{type}}.mod 0i64.step(to: %mod, by: %mod // 1000000).each do |x| {{type}}.new(x).{{method}}.should eq x.{{method}} end end private macro check_method_mod(type, method) %mod = {{type}}.mod 0i64.step(to: %mod, by: %mod // 1000000).each do |x| {{type}}.new(x).{{method}}.should eq x.{{method}} % %mod end end describe "Mint" do it ".[]" do Mint[0, 1, 2, 3, MOD1, MOD1 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint)) Mint2[0, 1, 2, 3, MOD2, MOD2 + 1].should eq [0, 1, 2, 3, 0, 1].map(&.to_m(Mint2)) Mint[0, 1, MOD1, MOD1 + 1, MOD1 * 2].map(&.value).should eq [0, 1, 0, 1, 0] end it ".mod" do Mint.mod.should eq MOD1 ModInt(42).mod.should eq 42 end it ".zero" do Mint.zero.should eq 0 end it "#initialize" do Mint.new.should eq 0 Mint.new(Int64::MIN).should eq Int64::MIN % MOD1 Mint.new(0).should eq 0 Mint.new(42).should eq 42 Mint.new(42i64).should eq 42 Mint.new(42i8).should eq 42 Mint.new(MOD1).should eq 0 Mint.new(MOD1 + 1).should eq 1 Mint.new(MOD1 * MOD1).should eq 0 Mint.new(Int64::MAX).should eq Int64::MAX % MOD1 end it "#+" do (+Mint.new).should eq 0 (+Mint.new(12)).should eq 12 end it "#-" do (-Mint.new).should eq 0 (-Mint.new(12)).should eq MOD1 - 12 end it "#+(other)" do a, b = Mint.new(1), Mint.new(-1) (a + a).should eq 2 (a + 3).should eq 4 (a + 3i64).should eq 4 (a + 3i8).should eq 4 (a + MOD1).should eq 1 (a + MOD1 * 2).should eq 1 (b + b).should eq MOD1 - 2 check_binary_operator(Mint, :+) check_binary_operator(Mint2, :+) end it "#-(other)" do a, b = Mint.new(3), Mint.new(-1) (a - Mint.new(4)).should eq MOD1 - 1 (a - 3).should eq 0 (a - 3i64).should eq 0 (a - 3i8).should eq 0 (a - 4).should eq MOD1 - 1 (a - MOD1).should eq 3 (Mint.zero - b).should eq 1 check_binary_operator(Mint, :-) check_binary_operator(Mint2, :-) end it "#*(other)" do a, b = Mint.new(3), Mint.new(-1) (a * 3).should eq 9 (a * a).should eq 9 (a * MOD1).should eq 0 (b * MOD1).should eq 0 (b * b).should eq 1 (b * Int64::MAX).should eq MOD1.pred * (Int64::MAX % MOD1) % MOD1 check_binary_operator(Mint, :*) check_binary_operator(Mint2, :*) end it "#/(other)" do a = Mint.new(3) (a / 1).should eq 3 (a / 2).should eq MOD1 // 2 + 2 (a / 3).should eq 1 {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000) do |x| 0i64.step(by: %mod, to: %mod // 999) do |y| next unless y.gcd(%mod) == 1 z = {{type}}.new(x) / y (z * y).should eq x end end {% end %} expect_raises(DivisionByZeroError) { a / 0 } expect_raises(DivisionByZeroError) { a / 0i8 } expect_raises(DivisionByZeroError) { a / MOD1 } expect_raises(DivisionByZeroError) { a / Mint.zero } end it "#//(other)" do a = Mint.new(3) (a // 1).should eq 3 (a // 2).should eq MOD1 // 2 + 2 (a // 3).should eq 1 {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000) do |x| 0i64.step(by: %mod, to: %mod // 999) do |y| next unless y.gcd(%mod) == 1 z = {{type}}.new(x) // y (z * y).should eq x end end {% end %} expect_raises(DivisionByZeroError) { a // 0 } expect_raises(DivisionByZeroError) { a // 0i8 } expect_raises(DivisionByZeroError) { a // MOD1 } expect_raises(DivisionByZeroError) { a // Mint.zero } end it "#**(other)" do a = Mint.new(3) (a ** 0).should eq 1 (a ** 1).should eq 3 (a ** 2).should eq 9 (a ** 20).should eq 486784380 (a ** (10i64**18)).should eq 246336683 (a.pred ** (10i64**18)).should eq 719476260 {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000) do |x| 0i64.step(by: Int64::MAX, to: Int64::MAX // 1000) do |e| m = {{type}}.new(x) ** e expect = AtCoder::Math.pow_mod(x, e, %mod) m.should eq expect end end {% end %} end it "#inv" do {% for type in [Mint, Mint2] %} %mod = {{type}}.mod 0i64.step(by: %mod, to: %mod // 1000000) do |x| next unless x.gcd(%mod) == 1 ({{type}}.new(x).inv * x).should eq 1 end {% end %} end it "#==(other)" do a = Mint.new(3) (a == a).should be_true (a == 3).should be_true (a == MOD1 + 3).should be_false (a == Mint.new(MOD1 + 3)).should be_true end it "#!=(other)" do a = Mint.new(3) (a != a).should be_false (a != MOD1 + 3).should be_true (a != Mint.new(MOD1 + 3)).should be_false end it "#succ" do Mint.new(0).succ.should eq 1 Mint.new(3).succ.should eq 4 Mint.new(MOD1).succ.should eq 1 Mint.new(-1).succ.should eq 0 check_method_mod(Mint, succ) check_method_mod(Mint2, succ) end it "#pred" do Mint.new(0).pred.should eq MOD1 - 1 Mint.new(3).pred.should eq 2 Mint.new(MOD1).pred.should eq MOD1 - 1 Mint.new(-1).pred.should eq MOD1 - 2 check_method_mod(Mint, pred) check_method_mod(Mint2, pred) end it "#abs" do Mint.new(0).abs.should eq 0 Mint.new(3).abs.should eq 3 Mint.new(MOD1).abs.should eq 0 Mint.new(-1).abs.should eq MOD1 - 1 check_method_mod(Mint, abs) check_method_mod(Mint2, abs) end it "#value" do Mint.new(0).value.should eq 0 Mint.new(3).value.should eq 3 Mint.new(MOD1).value.should eq 0 Mint.new(-1).value.should eq MOD1 - 1 end it "#to_s" do Mint.new(0).to_s.should eq "0" Mint.new(3).to_s.should eq "3" Mint.new(MOD1).to_s.should eq "0" Mint.new(-1).to_s.should eq MOD1.pred.to_s check_method(Mint, to_s) check_method(Mint2, to_s) end it "#inspect" do Mint.new(0).inspect.should eq "0" Mint.new(3).inspect.should eq "3" Mint.new(MOD1).inspect.should eq "0" Mint.new(-1).inspect.should eq (MOD1 - 1).inspect check_method(Mint, inspect) check_method(Mint2, inspect) end end describe Int do it "#to_m" do (-1).to_m(Mint).should eq MOD1 - 1 (-1i8).to_m(Mint).should eq MOD1 - 1 0.to_m(Mint).should eq 0 1i64.to_m(Mint).should eq 1 MOD1.to_m(Mint).should eq 0 (-1).to_m(Mint2).should eq MOD2 - 1 end end describe String do it "#to_m" do "-1".to_m(Mint).should eq MOD1 - 1 "0".to_m(Mint).should eq 0 "1".to_m(Mint).should eq 1 MOD1.pred.to_s.to_m(Mint).should eq MOD1 - 1 MOD1.to_s.to_m(Mint).should eq 0 "-1".to_m(Mint2).should eq MOD2 - 1 end end