ac-library-rb 0.5.2 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|