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
102 changes: 102 additions & 0 deletions ModInt/ModInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,55 @@ public int value() {
public ModInt add(ModInt mi) {
return new ModInt(ma.add(value, mi.value));
}
public ModInt add(ModInt mi1, ModInt mi2) {
return new ModInt(ma.add(value, mi1.value)).addAsg(mi2);
}
public ModInt add(ModInt mi1, ModInt mi2, ModInt mi3) {
return new ModInt(ma.add(value, mi1.value)).addAsg(mi2).addAsg(mi3);
}
public ModInt add(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4) {
return new ModInt(ma.add(value, mi1.value)).addAsg(mi2).addAsg(mi3).addAsg(mi4);
}
public ModInt add(ModInt mi1, ModInt... mis) {
ModInt mi = add(mi1);
for (ModInt m : mis) mi.addAsg(m);
return mi;
}
public ModInt add(long mi) {
return new ModInt(ma.add(value, ma.remainder(mi)));
}
public ModInt sub(ModInt mi) {
return new ModInt(ma.sub(value, mi.value));
}
public ModInt sub(long mi) {
return new ModInt(ma.sub(value, ma.remainder(mi)));
}
public ModInt mul(ModInt mi) {
return new ModInt(ma.mul(value, mi.value));
}
public ModInt mul(ModInt mi1, ModInt mi2) {
return new ModInt(ma.mul(value, mi1.value)).mulAsg(mi2);
}
public ModInt mul(ModInt mi1, ModInt mi2, ModInt mi3) {
return new ModInt(ma.mul(value, mi1.value)).mulAsg(mi2).mulAsg(mi3);
}
public ModInt mul(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4) {
return new ModInt(ma.mul(value, mi1.value)).mulAsg(mi2).mulAsg(mi3).mulAsg(mi4);
}
public ModInt mul(ModInt mi1, ModInt... mis) {
ModInt mi = mul(mi1);
for (ModInt m : mis) mi.mulAsg(m);
return mi;
}
public ModInt mul(long mi) {
return new ModInt(ma.mul(value, ma.remainder(mi)));
}
public ModInt div(ModInt mi) {
return new ModInt(ma.div(value, mi.value));
}
public ModInt div(long mi) {
return new ModInt(ma.div(value, ma.remainder(mi)));
}
public ModInt inv() {
return new ModInt(ma.inv(value));
}
Expand All @@ -58,18 +98,60 @@ public ModInt addAsg(ModInt mi) {
this.value = ma.add(value, mi.value);
return this;
}
public ModInt addAsg(ModInt mi1, ModInt mi2) {
return addAsg(mi1).addAsg(mi2);
}
public ModInt addAsg(ModInt mi1, ModInt mi2, ModInt mi3) {
return addAsg(mi1).addAsg(mi2).addAsg(mi3);
}
public ModInt addAsg(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4) {
return addAsg(mi1).addAsg(mi2).addAsg(mi3).addAsg(mi4);
}
public ModInt addAsg(ModInt... mis) {
for (ModInt m : mis) addAsg(m);
return this;
}
public ModInt addAsg(long mi) {
this.value = ma.add(value, ma.remainder(mi));
return this;
}
public ModInt subAsg(ModInt mi) {
this.value = ma.sub(value, mi.value);
return this;
}
public ModInt subAsg(long mi) {
this.value = ma.sub(value, ma.remainder(mi));
return this;
}
public ModInt mulAsg(ModInt mi) {
this.value = ma.mul(value, mi.value);
return this;
}
public ModInt mulAsg(ModInt mi1, ModInt mi2) {
return mulAsg(mi1).mulAsg(mi2);
}
public ModInt mulAsg(ModInt mi1, ModInt mi2, ModInt mi3) {
return mulAsg(mi1).mulAsg(mi2).mulAsg(mi3);
}
public ModInt mulAsg(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4) {
return mulAsg(mi1).mulAsg(mi2).mulAsg(mi3).mulAsg(mi4);
}
public ModInt mulAsg(ModInt... mis) {
for (ModInt m : mis) mulAsg(m);
return this;
}
public ModInt mulAsg(long mi) {
this.value = ma.mul(value, ma.remainder(mi));
return this;
}
public ModInt divAsg(ModInt mi) {
this.value = ma.div(value, mi.value);
return this;
}
public ModInt divAsg(long mi) {
this.value = ma.div(value, ma.remainder(mi));
return this;
}
@Override
public String toString() {
return String.valueOf(value());
Expand All @@ -90,6 +172,7 @@ public int hashCode() {

private interface ModArithmetic {
public int mod();
public int remainder(long value);
public int add(int a, int b);
public int sub(int a, int b);
public int mul(int a, int b);
Expand Down Expand Up @@ -119,6 +202,7 @@ public static ModArithmetic of(int mod) {

static final class ModArithmetic1 implements ModArithmetic {
public int mod() {return 1;}
public int remainder(long value) {return 0;}
public int add(int a, int b) {return 0;}
public int sub(int a, int b) {return 0;}
public int mul(int a, int b) {return 0;}
Expand All @@ -127,6 +211,7 @@ static final class ModArithmetic1 implements ModArithmetic {
}
static final class ModArithmetic2 implements ModArithmetic {
public int mod() {return 2;}
public int remainder(long value) {return (int) (value & 1);}
public int add(int a, int b) {return a ^ b;}
public int sub(int a, int b) {return a ^ b;}
public int mul(int a, int b) {return a & b;}
Expand All @@ -144,6 +229,9 @@ static final class ModArithmetic998244353 implements ModArithmetic {
public int mod() {
return mod;
}
public int remainder(long value) {
return (int) ((value %= mod) < 0 ? value + mod : value);
}
public int add(int a, int b) {
int res = a + b;
return res >= mod ? res - mod : res;
Expand Down Expand Up @@ -192,6 +280,9 @@ static final class ModArithmetic1000000007 implements ModArithmetic {
public int mod() {
return mod;
}
public int remainder(long value) {
return (int) ((value %= mod) < 0 ? value + mod : value);
}
public int add(int a, int b) {
int res = a + b;
return res >= mod ? res - mod : res;
Expand Down Expand Up @@ -267,6 +358,10 @@ private int reduce(long x) {
return (int) (x < mod ? x : x - mod);
}
@Override
public int remainder(long value) {
return generate((value %= mod) < 0 ? value + mod : value);
}
@Override
public int mul(int a, int b) {
return reduce((long) a * b);
}
Expand Down Expand Up @@ -306,6 +401,10 @@ private int reduce(long x) {
return (int) (x < mod ? x : x - mod);
}
@Override
public int remainder(long value) {
return (int) ((value %= mod) < 0 ? value + mod : value);
}
@Override
public int mul(int a, int b) {
return reduce((long) a * b);
}
Expand All @@ -318,6 +417,9 @@ public ModArithmeticDynamic(int mod) {
public int mod() {
return mod;
}
public int remainder(long value) {
return (int) ((value %= mod) < 0 ? value + mod : value);
}
public int add(int a, int b) {
int sum = a + b;
return sum >= mod ? sum - mod : sum;
Expand Down
118 changes: 105 additions & 13 deletions ModInt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,47 +79,93 @@ public int mod()
public int value()
```

保持している値を返します.__注意: `ModInt` のフィールド `int value` に直接アクセスはしないで下さい. 正しい値が取得できない可能性があります.__
保持している値を返します.__注意: `ModInt` のフィールド `int value` に直接アクセスしないで下さい. 正しい値が取得できない可能性があります.__

計算量: $O(1)$

#### add

```java
// (1)
public ModInt add(ModInt mi)
// (2)
public ModInt add(ModInt mi1, ModInt mi2)
// (3)
public ModInt add(ModInt mi1, ModInt mi2, ModInt mi3)
// (4)
public ModInt add(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4)
// (5)
public ModInt add(ModInt mi1, ModInt... mis)
// (6)
public ModInt add(long mi)
```

値 `(a + b) % mod` を持つ `ModInt` を新たに生成します (`a` および `b` の値は書き換わりません).
1. 値 `(a + b) % mod` を持つ `ModInt` を新たに生成します.
2. 値 `(a + b + c) % mod` を持つ `ModInt` を新たに生成します.
3. 値 `(a + b + c + d) % mod` を持つ `ModInt` を新たに生成します.
4. 値 `(a + b + c + d + e) % mod` を持つ `ModInt` を新たに生成します.
5. 値 `(a + b + c + d + e + f + ...) % mod` を持つ `ModInt` を新たに生成します.
6. 値 `(a + b) % mod` を持つ `ModInt` を新たに生成します. 定数の加算でこれを用いると便利です.

計算量: $O(1)$
計算量:

- (1)~(4), (6): $O(1)$
- (5): $n$ を可変長引数の長さとして,$O(n)$

#### sub

```java
// (1)
public ModInt sub(ModInt mi)
// (2)
public ModInt sub(long mi)
```

値 `(a - b) % mod` を持つ `ModInt` を新たに生成します (`a` および `b` の値は書き換わりません).
1. 値 `(a - b) % mod` を持つ `ModInt` を新たに生成します.
2. 値 `(a - b) % mod` を持つ `ModInt` を新たに生成します. 定数の減算でこれを用いると便利です.

計算量: $O(1)$

#### mul

```java
// (1)
public ModInt mul(ModInt mi)
// (2)
public ModInt mul(ModInt mi1, ModInt mi2)
// (3)
public ModInt mul(ModInt mi1, ModInt mi2, ModInt mi3)
// (4)
public ModInt mul(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4)
// (5)
public ModInt mul(ModInt mi1, ModInt... mis)
// (6)
public ModInt mul(long mi)
```

値 `(a * b) % mod` を持つ `ModInt` を新たに生成します (`a` および `b` の値は書き換わりません).
1. 値 `(a * b) % mod` を持つ `ModInt` を新たに生成します.
2. 値 `(a * b * c) % mod` を持つ `ModInt` を新たに生成します.
3. 値 `(a * b * c * d) % mod` を持つ `ModInt` を新たに生成します.
4. 値 `(a * b * c * d * e) % mod` を持つ `ModInt` を新たに生成します.
5. 値 `(a * b * c * d * e * f * ...) % mod` を持つ `ModInt` を新たに生成します.
6. 値 `(a * b) % mod` を持つ `ModInt` を新たに生成します. 定数の乗算でこれを用いると便利です.

計算量: $O(1)$
計算量:

- (1)~(4), (6): $O(1)$
- (5): $n$ を可変長引数の長さとして,$O(n)$

#### div

```java
// (1)
public ModInt div(ModInt mi)
// (2)
public ModInt div(long mi)
```

値 `(a * b^(-1)) % mod` を持つ `ModInt` を新たに生成します (`a` および `b` の値は書き換わりません). ただし,`b^(-1)` は `(b * x) % mod = 1` を満たす `x` です.
1. 値 `(a * b^(-1)) % mod` を持つ `ModInt` を新たに生成します. ただし,`b^(-1)` は `(b * x) % mod = 1` を満たす `x` です.
2. 値 `(a * b^(-1)) % mod` を持つ `ModInt` を新たに生成します. 定数の除算でこれを用いると便利です.

計算量: $O(\log \mod)$

Expand Down Expand Up @@ -154,40 +200,86 @@ public ModInt pow(long n)
#### addAsg

```java
// (1)
public ModInt addAsg(ModInt mi)
// (2)
public ModInt addAsg(ModInt mi1, ModInt mi2)
// (3)
public ModInt addAsg(ModInt mi1, ModInt mi2, ModInt mi3)
// (4)
public ModInt addAsg(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4)
// (5)
public ModInt addAsg(ModInt... mis)
// (6)
public ModInt addAsg(long mi)
```

`a += b` を行います. `a` の値は書き換えられます.
1. `a += b` を行います. `a` の値は書き換えられます.
2. `a += b + c` を行います. `a` の値は書き換えられます.
3. `a += b + c + d` を行います. `a` の値は書き換えられます.
4. `a += b + c + d + e` を行います. `a` の値は書き換えられます.
5. `a += b + c + d + e + f + ...` を行います. `a` の値は書き換えられます.
6. `a += b` を行います. `a` の値は書き換えられます. 定数の加算でこれを用いると便利です.

計算量: $O(1)$
計算量:

- (1)~(4), (6): $O(1)$
- (5): $n$ を可変長引数の長さとして,$O(n)$

#### subAsg

```java
// (1)
public ModInt subAsg(ModInt mi)
// (2)
public ModInt subAsg(long mi)
```

`a -= b` を行います. `a` の値は書き換えられます.
1. `a -= b` を行います. `a` の値は書き換えられます.
2. `a -= b` を行います. `a` の値は書き換えられます. 定数の減算でこれを用いると便利です.

計算量: $O(1)$

#### mulAsg

```java
// (1)
public ModInt mulAsg(ModInt mi)
// (2)
public ModInt mulAsg(ModInt mi1, ModInt mi2)
// (3)
public ModInt mulAsg(ModInt mi1, ModInt mi2, ModInt mi3)
// (4)
public ModInt mulAsg(ModInt mi1, ModInt mi2, ModInt mi3, ModInt mi4)
// (5)
public ModInt mulAsg(ModInt... mis)
// (6)
public ModInt mulAsg(long mi)
```

`a *= b` を行います. `a` の値は書き換えられます.
1. `a *= b` を行います. `a` の値は書き換えられます.
2. `a *= b * c` を行います. `a` の値は書き換えられます.
3. `a *= b * c * d` を行います. `a` の値は書き換えられます.
4. `a *= b * c * d * e` を行います. `a` の値は書き換えられます.
5. `a *= b * c * d * e * f * ...` を行います. `a` の値は書き換えられます.
6. `a *= b` を行います. `a` の値は書き換えられます. 定数の乗算でこれを用いると便利です.

計算量: $O(1)$
計算量:

- (1)~(4), (6): $O(1)$
- (5): $n$ を可変長引数の長さとして,$O(n)$

#### divAsg

```java
// (1)
public ModInt divAsg(ModInt mi)
// (2)
public ModInt divAsg(long mi)
```

`a *= b^(-1)` を行います (`a /= b`). `a` の値は書き換えられます. ただし,`b^(-1)` は `(b * x) % mod = 1` を満たす `x` です.
1. `a *= b^(-1)` を行います. `a` の値は書き換えられます. ただし,`b^(-1)` は `(b * x) % mod = 1` を満たす `x` です.
2. `a *= b^(-1)` を行います. `a` の値は書き換えられます. 定数の除算でこれを用いると便利です.

計算量: $O(\log \mod)$

Expand Down