ac-library-rb 0.5.2 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/README.md +9 -2
- data/ac-library-rb.gemspec +1 -0
- data/bin/lock_lib.rb +5 -1
- data/document_en/dsu.md +2 -2
- data/document_en/max_flow.md +1 -1
- data/document_en/min_cost_flow.md +1 -1
- data/document_en/segtree.md +22 -5
- data/document_en/two_sat.md +1 -1
- data/document_ja/dsu.md +1 -3
- data/document_ja/lazy_segtree.md +9 -7
- data/document_ja/max_flow.md +1 -1
- data/document_ja/min_cost_flow.md +1 -1
- data/document_ja/scc.md +4 -3
- data/document_ja/segtree.md +42 -9
- data/document_ja/two_sat.md +1 -1
- data/lib/ac-library-rb/version.rb +1 -1
- data/lib/convolution.rb +21 -0
- data/lib/core_ext/all.rb +11 -0
- data/lib/crt.rb +3 -1
- data/lib/dsu.rb +11 -8
- data/lib/fenwick_tree.rb +22 -8
- data/lib/floor_sum.rb +33 -10
- data/lib/lazy_segtree.rb +29 -3
- data/lib/max_flow.rb +10 -4
- data/lib/min_cost_flow.rb +13 -7
- data/lib/scc.rb +21 -13
- data/lib/segtree.rb +28 -22
- data/lib/two_sat.rb +7 -5
- data/lib_helpers/ac-library-rb.rb +24 -0
- data/lib_lock/ac-library-rb/convolution.rb +21 -0
- data/lib_lock/ac-library-rb/core_ext/all.rb +11 -0
- data/lib_lock/ac-library-rb/core_ext/modint.rb +3 -3
- data/lib_lock/ac-library-rb/crt.rb +3 -1
- data/lib_lock/ac-library-rb/dsu.rb +11 -8
- data/lib_lock/ac-library-rb/fenwick_tree.rb +22 -8
- data/lib_lock/ac-library-rb/floor_sum.rb +33 -10
- data/lib_lock/ac-library-rb/lazy_segtree.rb +29 -3
- data/lib_lock/ac-library-rb/max_flow.rb +10 -4
- data/lib_lock/ac-library-rb/min_cost_flow.rb +13 -7
- data/lib_lock/ac-library-rb/scc.rb +21 -13
- data/lib_lock/ac-library-rb/segtree.rb +28 -22
- data/lib_lock/ac-library-rb/two_sat.rb +7 -5
- metadata +20 -4
- data/lib_lock/ac-library-rb.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f7674ea5a0a95f6cad7945415632a06bf91a515cde31d1c08320d5e9561fc0e
|
4
|
+
data.tar.gz: d6bb650ec23b99f6180f5e8413644863dae78c7923d79249bcadcb9a8a1fcaa0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d549b2be1fa15a519b8e1d692bbbd03ccd6c0f0b2d94787dbdc48c44ce9274c92ed5e7d6148c195ef73a545ba9951a64f74e84f39eed62e6c12a2eaaf386fcb9
|
7
|
+
data.tar.gz: 5f2b39beb3aacb21ac0fec142b550baf20b6343ed4fabce3ca303d8466bd632af71ce33d911b6a0494425234afa928949d33a670d490a91f9f5441c535586ae4
|
data/.rubocop.yml
CHANGED
@@ -121,6 +121,9 @@ Style/BlockDelimiters:
|
|
121
121
|
- 'test/z_algorithm_test.rb'
|
122
122
|
Style/Documentation:
|
123
123
|
Enabled: false
|
124
|
+
tyle/EmptyElse:
|
125
|
+
Exclude:
|
126
|
+
- 'test/segtree_test.rb'
|
124
127
|
Style/GlobalVars:
|
125
128
|
AutoCorrect: false
|
126
129
|
Exclude:
|
@@ -128,6 +131,9 @@ Style/GlobalVars:
|
|
128
131
|
- 'test/lazy_segtree_test.rb'
|
129
132
|
Style/FrozenStringLiteralComment:
|
130
133
|
Enabled: false
|
134
|
+
Style/InfiniteLoop:
|
135
|
+
Exclude:
|
136
|
+
- 'lib/floor_sum.rb'
|
131
137
|
Style/InverseMethods:
|
132
138
|
AutoCorrect: false
|
133
139
|
Exclude:
|
data/README.md
CHANGED
@@ -37,7 +37,7 @@ This is not limited to ac-library-rb, but I will show you how to install the two
|
|
37
37
|
- By `gem` command, `gem install ac-library-rb`.
|
38
38
|
- By using the gem bundler's commands.
|
39
39
|
|
40
|
-
By
|
40
|
+
#### By gem command, `gem install ac-library-rb`
|
41
41
|
|
42
42
|
Execute `gem install ac-library-rb` by using the gem command included in Ruby itself.
|
43
43
|
|
@@ -100,7 +100,14 @@ $ rake
|
|
100
100
|
$ ruby test/fenwick_tree_test.rb
|
101
101
|
```
|
102
102
|
|
103
|
-
# Other
|
103
|
+
# Other
|
104
|
+
|
105
|
+
## Other languages's ac-library
|
106
|
+
|
107
|
+
- [Unofficial Portings of AtCoder Library](https://docs.google.com/spreadsheets/d/19jMAqUbv98grVkLV_Lt54x5B8ILoTcvBzG8EbSvf5gY/edit#gid=0) (by [not522-san](https://github.com/not522))
|
108
|
+
|
109
|
+
|
110
|
+
## Other language Japanese version
|
104
111
|
|
105
112
|
[README 日本語バージョン(ver. Japanese)](README.ja.md)
|
106
113
|
- [ライブラリ目次: index.md](https://github.com/universato/ac-library-rb/blob/master/document_ja/index.md)
|
data/ac-library-rb.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "minitest"
|
22
22
|
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "simplecov"
|
23
24
|
|
24
25
|
# Specify which files should be added to the gem when it is released.
|
25
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
data/bin/lock_lib.rb
CHANGED
@@ -17,6 +17,10 @@ Dir.glob(lib_path) do |file|
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# copy library from `lib/core_ext` to `lib_lock/ac-library-rb/core_ext`
|
20
|
+
ac_library_rb_classes = %w[ModInt FenwickTree PriorityQueue]
|
21
|
+
replaces = ac_library_rb_classes.to_h{ |cls| ["#{cls}.new", "AcLibraryRb::#{cls}.new"] }
|
22
|
+
pattern = Regexp.new(replaces.keys.join('|'))
|
23
|
+
|
20
24
|
lib_path = File.expand_path('../lib/core_ext/**', __dir__)
|
21
25
|
lock_dir = File.expand_path('../lib_lock/ac-library-rb/core_ext', __dir__)
|
22
26
|
Dir.glob(lib_path) do |file|
|
@@ -24,6 +28,6 @@ Dir.glob(lib_path) do |file|
|
|
24
28
|
|
25
29
|
path = Pathname.new(lock_dir) + Pathname.new(file).basename
|
26
30
|
File.open(path, "w") do |f|
|
27
|
-
f.puts File.readlines(file)
|
31
|
+
f.puts File.readlines(file).map{ |text| text.gsub(pattern, replaces) }
|
28
32
|
end
|
29
33
|
end
|
data/document_en/dsu.md
CHANGED
@@ -27,7 +27,7 @@ p d.size(2) # => 2
|
|
27
27
|
|
28
28
|
## Class Method
|
29
29
|
|
30
|
-
### new(n
|
30
|
+
### new(n) -> DSU
|
31
31
|
|
32
32
|
```rb
|
33
33
|
d = DSU.new(n)
|
@@ -41,7 +41,7 @@ It creates an undirected graph with `n` vertices and `0` edges.
|
|
41
41
|
|
42
42
|
**alias**
|
43
43
|
|
44
|
-
- `DSU`, `
|
44
|
+
- `DSU`, `UnionFind`
|
45
45
|
|
46
46
|
## Instance Methods
|
47
47
|
|
data/document_en/max_flow.md
CHANGED
data/document_en/segtree.md
CHANGED
@@ -4,7 +4,8 @@ Segment Tree
|
|
4
4
|
|
5
5
|
## Class Methods
|
6
6
|
|
7
|
-
### new(n, e,
|
7
|
+
### new(n, e){ |x, y| ... } -> Segtree
|
8
|
+
### new(n, op, e) -> Segtree
|
8
9
|
|
9
10
|
```rb
|
10
11
|
seg = Segtree.new(n, e) { |x, y| ... }
|
@@ -15,7 +16,9 @@ It creates an array `a` of length `n`. All the elements are initialized to `e`.
|
|
15
16
|
- `block`: returns `op(x, y)`
|
16
17
|
- `e`: identity element.
|
17
18
|
|
18
|
-
|
19
|
+
|
20
|
+
### new(ary, e){ |x, y| ... } -> Segtree
|
21
|
+
### new(ary, op, e) -> Segtree
|
19
22
|
|
20
23
|
```rb
|
21
24
|
seg = Segtree.new(ary, e) { |x, y| ... }
|
@@ -104,26 +107,38 @@ It returns `op(a[0], ..., a[n - 1])`.
|
|
104
107
|
seg.max_right(l, &f)
|
105
108
|
```
|
106
109
|
|
110
|
+
It applies binary search on the segment tree.
|
111
|
+
|
112
|
+
It returns an index `r` that satisfies both of the following.
|
113
|
+
|
114
|
+
- `r = l` or `f(prod(l, r)) = true`
|
115
|
+
- `r = n` or `f(prod(l, r + 1)) = false`
|
116
|
+
|
117
|
+
|
107
118
|
**Constraints**
|
108
119
|
|
120
|
+
- `f(e) = true`
|
109
121
|
- `0 ≦ l ≦ n`
|
110
122
|
|
111
123
|
**Complexity**
|
112
124
|
|
113
125
|
- `O(log n)`
|
114
126
|
|
115
|
-
It applies binary search on the segment tree.
|
116
|
-
|
117
127
|
### min_left(r, &f) -> Integer
|
118
128
|
|
119
129
|
```ruby
|
120
130
|
seg.min_left(r, &f)
|
121
131
|
```
|
122
132
|
|
123
|
-
It applies binary search on the segment tree.
|
133
|
+
It applies binary search on the segment tree.
|
134
|
+
It returns an index l that satisfies both of the following.
|
135
|
+
|
136
|
+
- `l = r` or `f(prod(l, r)) = true`
|
137
|
+
- `l = 0` or `f(prod(l - 1, r)) = false`
|
124
138
|
|
125
139
|
**Constraints**
|
126
140
|
|
141
|
+
- `f(e) = true`
|
127
142
|
- `0 ≦ r ≦ n`
|
128
143
|
|
129
144
|
**Complexity**
|
@@ -133,6 +148,8 @@ It applies binary search on the segment tree.
|
|
133
148
|
## Verified
|
134
149
|
|
135
150
|
- [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
|
151
|
+
- [AC Code(884ms) max_right](https://atcoder.jp/contests/practice2/submissions/23196480)
|
152
|
+
- [AC Code(914ms) min_left](https://atcoder.jp/contests/practice2/submissions/23197311)
|
136
153
|
- [F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
|
137
154
|
- [AC Code(1538ms)](https://atcoder.jp/contests/abc185/submissions/18746817): Segtree(xor)
|
138
155
|
- [AC Code(821ms)](https://atcoder.jp/contests/abc185/submissions/18769200): FenwickTree(BIT) xor
|
data/document_en/two_sat.md
CHANGED
data/document_ja/dsu.md
CHANGED
@@ -30,7 +30,7 @@ p d.size(2) # => 2
|
|
30
30
|
|
31
31
|
## 特異メソッド
|
32
32
|
|
33
|
-
### new(n
|
33
|
+
### new(n) -> DSU
|
34
34
|
|
35
35
|
```rb
|
36
36
|
d = DSU.new(n)
|
@@ -48,9 +48,7 @@ d = DSU.new(n)
|
|
48
48
|
**エイリアス**
|
49
49
|
|
50
50
|
- `DSU`
|
51
|
-
- `DisjointSetUnion`
|
52
51
|
- `UnionFind`
|
53
|
-
- `UnionFindTree`
|
54
52
|
|
55
53
|
## インスタンスメソッド
|
56
54
|
|
data/document_ja/lazy_segtree.md
CHANGED
@@ -132,7 +132,7 @@ LazySegtree上で、二分探索をします。
|
|
132
132
|
## Verified
|
133
133
|
|
134
134
|
問題のリンクです。Verified済みです。解答はテストコードをご参考ください。
|
135
|
-
- [AIZU ONLINE JUDGE DSL\_2\_F RMQ and RUQ](
|
135
|
+
- [AIZU ONLINE JUDGE DSL\_2\_F RMQ and RUQ](https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_F) ([旧DSL_2_F](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F))
|
136
136
|
- [AIZU ONLINE JUDGE DSL\_2\_G RSQ and RAQ](https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_G) ([旧DSL_2_G](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G))
|
137
137
|
- [AIZU ONLINE JUDGE DSL\_2\_H RMQ and RAQ](https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_H) ([旧DSL_2_H](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_H))
|
138
138
|
- [AIZU ONLINE JUDGE DSL\_2\_I RSQ and RUQ](https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_I) ([旧DSL_2_I](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_I))
|
@@ -155,13 +155,15 @@ LazySegtree上で、二分探索をします。
|
|
155
155
|
- [本家ライブラリの実装コード lazysegtree.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/lazysegtree.hpp)
|
156
156
|
- [本家ライブラリのテストコード lazysegtree_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/unittest/lazysegtree_test.cpp)
|
157
157
|
- セグメントツリーについて
|
158
|
-
- [
|
159
|
-
- [
|
158
|
+
- [2017/3 hogecoder: セグメント木をソラで書きたいあなたに](https://tsutaj.hatenablog.com/entry/2017/03/29/204841)
|
159
|
+
- [2017/3 hogecoder: 遅延評価セグメント木をソラで書きたいあなたに](https://tsutaj.hatenablog.com/entry/2017/03/30/224339)
|
160
|
+
- [2017/7 はまやんはまやんはまやん: 競技プログラミングにおけるセグメントツリー問題まとめ](https://blog.hamayanhamayan.com/entry/2017/07/08/173120)
|
161
|
+
- [2020/2 ageprocpp Qiita: Segment Treeことはじめ【後編】](https://qiita.com/ageprocpp/items/9ea58ac181d31cfdfe02)
|
160
162
|
- AtCooderLibrary(ACL)のLazySegtreeについて
|
161
|
-
- [
|
162
|
-
- [
|
163
|
-
- [ACLPC: K–Range Affine Range Sumの解説
|
164
|
-
- [
|
163
|
+
- [2020/9/22 ARMERIA: 使い方](https://betrue12.hateblo.jp/entry/2020/09/22/194541)
|
164
|
+
- [2020/9/23 ARMERIA: チートシート](https://betrue12.hateblo.jp/entry/2020/09/23/005940)
|
165
|
+
- [2020/9/27 optのブログ: ACLPC: K–Range Affine Range Sumの解説](https://opt-cp.com/cp/lazysegtree-aclpc-k/)
|
166
|
+
- [2020/9/27 buyoh.hateblo.jp: ACL 基礎実装例集](https://buyoh.hateblo.jp/entry/2020/09/27/190144)
|
165
167
|
|
166
168
|
## 本家ライブラリとの違い
|
167
169
|
|
data/document_ja/max_flow.md
CHANGED
data/document_ja/scc.md
CHANGED
@@ -6,7 +6,7 @@ Strongly Connected Components
|
|
6
6
|
|
7
7
|
## 特異メソッド
|
8
8
|
|
9
|
-
### new(n
|
9
|
+
### new(n) -> SCC
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
graph = SCC.new(6)
|
@@ -50,8 +50,9 @@ graph.scc
|
|
50
50
|
|
51
51
|
## Verified
|
52
52
|
|
53
|
-
[ALPC: G \- SCC](https://atcoder.jp/contests/practice2/tasks/practice2_g)
|
54
|
-
- [2538ms 2020/9/8](https://atcoder.jp/contests/practice2/submissions/16569175)
|
53
|
+
- [ALPC: G \- SCC](https://atcoder.jp/contests/practice2/tasks/practice2_g)
|
54
|
+
- [2538ms 2020/9/8](https://atcoder.jp/contests/practice2/submissions/16569175)
|
55
|
+
- [競プロ典型 90 問: 021 - Come Back in One Piece][https://atcoder.jp/contests/typical90/tasks/typical90_u]
|
55
56
|
|
56
57
|
# 参考リンク
|
57
58
|
|
data/document_ja/segtree.md
CHANGED
@@ -4,7 +4,8 @@
|
|
4
4
|
|
5
5
|
## 特異メソッド
|
6
6
|
|
7
|
-
### new(arg, e,
|
7
|
+
### new(arg, e){ |x, y| ... } -> Segtree
|
8
|
+
### new(arg, op, e) -> Segtree
|
8
9
|
|
9
10
|
```rb
|
10
11
|
seg = Segtree.new(arg, e) { |x, y| ... }
|
@@ -94,11 +95,24 @@ seg.all_prod
|
|
94
95
|
seg.max_right(l, &f)
|
95
96
|
```
|
96
97
|
|
97
|
-
Segtree
|
98
|
+
Segtree上で`l <= r <= n`の範囲で、`f(prod(l, r))`の結果を二分探索をして条件に当てはまる`r`を返します。
|
98
99
|
|
99
|
-
|
100
|
+
以下の条件を両方満たす `r` (`l <= r <= n`)を(いずれか一つ)返します。
|
100
101
|
|
101
|
-
|
102
|
+
- `r = l` もしくは `f(prod(l, r))`が`true`となる`r`
|
103
|
+
- `r = n` もしくは `f(prod(l, r + 1))`が`false`となる`r`
|
104
|
+
|
105
|
+
`prod(l, r)`は半開区間`[l, r)`であることに注意。
|
106
|
+
|
107
|
+
**制約**
|
108
|
+
|
109
|
+
- `f`を同じ引数で呼んだとき、返り値は同じ。
|
110
|
+
- `f(e)`が`true`
|
111
|
+
- `0 ≦ l ≦ n`
|
112
|
+
|
113
|
+
**計算量**
|
114
|
+
|
115
|
+
- `O(log n)`
|
102
116
|
|
103
117
|
### min_left(r, &f) -> Integer
|
104
118
|
|
@@ -106,15 +120,30 @@ Segtree上で二分探索をします。
|
|
106
120
|
seg.min_left(r, &f)
|
107
121
|
```
|
108
122
|
|
109
|
-
Segtree
|
123
|
+
Segtree上で`0 <= l <= r`の範囲で、`f(prod(l, r))`の結果を二分探索をして条件に当てはまる`l`を返します。
|
124
|
+
|
125
|
+
以下の条件を両方満たす `l` (`0 <= l <= r`)を(いずれか一つ)返します。
|
110
126
|
|
111
|
-
|
127
|
+
- `l = r` もしくは `f(prod(l, r))`が`true`となる`l`
|
128
|
+
- `l = 0` もしくは `f(prod(l - 1, r))`が`false`となる`l`
|
129
|
+
|
130
|
+
`prod(l, r)`は半開区間`[l, r)`であることに注意。
|
131
|
+
|
132
|
+
**制約**
|
133
|
+
|
134
|
+
- `f`を同じ引数で呼んだとき、返り値は同じ。
|
135
|
+
- `f(e)`が`true`
|
136
|
+
- `0 ≦ l ≦ n`
|
137
|
+
|
138
|
+
**計算量**
|
112
139
|
|
113
|
-
|
140
|
+
- `O(log n)`
|
114
141
|
|
115
142
|
## Verified
|
116
143
|
|
117
144
|
- [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
|
145
|
+
- [AC Code(884ms) max_right](https://atcoder.jp/contests/practice2/submissions/23196480)
|
146
|
+
- [AC Code(914ms) min_left](https://atcoder.jp/contests/practice2/submissions/23197311)
|
118
147
|
|
119
148
|
- [ABC185: F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
|
120
149
|
- xorのセグメントツリーの基本的な典型問題です。FenwickTree(BIT)をxorに改造するだけでも解けます。
|
@@ -127,14 +156,18 @@ Segtree上で二分探索をします。
|
|
127
156
|
- [当ライブラリの実装コード segtree.rb](https://github.com/universato/ac-library-rb/blob/master/lib/segtree.rb)
|
128
157
|
- [当ライブラリのテストコード segtree.rb](https://github.com/universato/ac-library-rb/blob/master/test/segtree_test.rb)
|
129
158
|
- テストコードも具体的な使い方として役に立つかもしれまん。
|
130
|
-
-
|
159
|
+
- 本家ライブラリ
|
131
160
|
- [本家ライブラリのドキュメント segtree.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/segtree.md)
|
132
161
|
- [本家のドキュメント appendix.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/appendix.md)
|
133
162
|
- [本家ライブラリの実装コード segtree.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/segtree.hpp)
|
134
163
|
- [本家ライブラリのテストコード segtree_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/unittest/segtree_test.cpp)
|
135
164
|
- [本家ライブラリのサンプルコード segtree_practice.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/example/segtree_practice.cpp)
|
136
165
|
- セグメントツリーについて
|
137
|
-
- [
|
166
|
+
- [2017/3 hogecoder: セグメント木をソラで書きたいあなたに](https://tsutaj.hatenablog.com/entry/2017/03/29/204841)
|
167
|
+
- [2017/7 はまやんはまやんはまやん: 競技プログラミングにおけるセグメントツリー問題まとめ](https://blog.hamayanhamayan.com/entry/2017/07/08/173120)
|
168
|
+
- [2017/12 ei1333の日記: ちょっと変わったセグメント木の使い方](https://ei1333.hateblo.jp/entry/2017/12/14/000000)
|
169
|
+
スライドが二分探索について詳しい
|
170
|
+
- [2020/2 ageprocpp@Qiita: Segment Treeことはじめ【前編](https://qiita.com/ageprocpp/items/f22040a57ad25d04d199)
|
138
171
|
|
139
172
|
## 本家ライブラリとの違い等
|
140
173
|
|
data/document_ja/two_sat.md
CHANGED
data/lib/convolution.rb
CHANGED
@@ -122,3 +122,24 @@ class Convolution
|
|
122
122
|
|
123
123
|
private :batterfly, :batterfly_inv, :bsf, :calc_primitive_root
|
124
124
|
end
|
125
|
+
|
126
|
+
# [EXPERIMENTAL]
|
127
|
+
def convolution(a, b, mod: 998244353, k: 35, z: 99)
|
128
|
+
n = a.size
|
129
|
+
m = b.size
|
130
|
+
return [] if n == 0 || m == 0
|
131
|
+
|
132
|
+
raise ArgumentError if a.min < 0 || b.min < 0
|
133
|
+
|
134
|
+
format = "%0#{k}x" # "%024x"
|
135
|
+
sa = ""
|
136
|
+
sb = ""
|
137
|
+
a.each{ |x| sa << (format % x) }
|
138
|
+
b.each{ |x| sb << (format % x) }
|
139
|
+
|
140
|
+
zero = '0'
|
141
|
+
s = zero * z + ("%x" % (sa.hex * sb.hex))
|
142
|
+
i = -(n + m - 1) * k - 1
|
143
|
+
|
144
|
+
Array.new(n + m - 1){ (s[i + 1..i += k] || zero).hex % mod }
|
145
|
+
end
|