ac-library-rb 0.5.1 → 0.5.2
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 +3 -0
 - data/README.ja.md +23 -0
 - data/README.md +2 -0
 - data/Rakefile +1 -1
 - data/document_en/lazy_segtree.md +20 -4
 - data/document_en/segtree.md +16 -0
 - data/document_ja/lazy_segtree.md +55 -13
 - data/document_ja/segtree.md +11 -3
 - data/lib/ac-library-rb/version.rb +1 -1
 - data/lib/lazy_segtree.rb +56 -9
 - data/lib/segtree.rb +16 -10
 - data/lib_lock/ac-library-rb/lazy_segtree.rb +56 -9
 - data/lib_lock/ac-library-rb/segtree.rb +16 -10
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: dc333b7ea588fedc3aaf0379408bb5cfa0cbe78ce78286375233e296ee687338
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 8b22febe194ced2ce838d6c5c59316e813acb1d3835988981bcd8ee48512a460
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: '09aae15824b338694ba75027deea63c5955e9056fb5af8ea3d382d0218fa6278ef8af2e9d281315ef45e01a4296e6b15688f221ea39ca03153a1799d7770cc7e'
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: db447beabc1e50f306a26a34128394e0c424d5291cb9df4b616bcadc3956a5acd90b6344fc80eaedadfa88efba96ee3918a622e582b8957c3b21be12f44b3636
         
     | 
    
        data/.rubocop.yml
    CHANGED
    
    | 
         @@ -91,6 +91,7 @@ Naming/FileName: 
     | 
|
| 
       91 
91 
     | 
    
         
             
                - 'lib_lock/ac-library-rb.rb'
         
     | 
| 
       92 
92 
     | 
    
         
             
            Naming/AccessorMethodName:
         
     | 
| 
       93 
93 
     | 
    
         
             
              Exclude:
         
     | 
| 
      
 94 
     | 
    
         
            +
                - 'lib/lazy_segtree.rb'
         
     | 
| 
       94 
95 
     | 
    
         
             
                - 'lib/modint.rb'
         
     | 
| 
       95 
96 
     | 
    
         
             
            Naming/MethodName:
         
     | 
| 
       96 
97 
     | 
    
         
             
              Exclude:
         
     | 
| 
         @@ -124,6 +125,7 @@ Style/GlobalVars: 
     | 
|
| 
       124 
125 
     | 
    
         
             
              AutoCorrect: false
         
     | 
| 
       125 
126 
     | 
    
         
             
              Exclude:
         
     | 
| 
       126 
127 
     | 
    
         
             
                - 'lib/modint.rb'
         
     | 
| 
      
 128 
     | 
    
         
            +
                - 'test/lazy_segtree_test.rb'
         
     | 
| 
       127 
129 
     | 
    
         
             
            Style/FrozenStringLiteralComment:
         
     | 
| 
       128 
130 
     | 
    
         
             
              Enabled: false
         
     | 
| 
       129 
131 
     | 
    
         
             
            Style/InverseMethods:
         
     | 
| 
         @@ -179,6 +181,7 @@ Style/SelfAssignment: 
     | 
|
| 
       179 
181 
     | 
    
         
             
            Style/Semicolon:
         
     | 
| 
       180 
182 
     | 
    
         
             
              Exclude:
         
     | 
| 
       181 
183 
     | 
    
         
             
                - 'lib/lazy_segtree.rb'
         
     | 
| 
      
 184 
     | 
    
         
            +
                - 'test/lazy_segtree_test.rb'
         
     | 
| 
       182 
185 
     | 
    
         
             
            Style/SlicingWithRange:
         
     | 
| 
       183 
186 
     | 
    
         
             
              Enabled: false
         
     | 
| 
       184 
187 
     | 
    
         
             
            Style/SpecialGlobalVars:
         
     | 
    
        data/README.ja.md
    CHANGED
    
    | 
         @@ -1,5 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # ac-library-rb
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            [](https://badge.fury.io/rb/ac-library-rb)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            ac-library-rbは、AtCoder Library (ACL)のRuby版です。
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
       5 
7 
     | 
    
         
             
            ACLの詳細は、以下をご覧ください.
         
     | 
| 
         @@ -114,12 +116,33 @@ ACL本家のレポジトリ名がac-libraryとハイフン区切りで、それ 
     | 
|
| 
       114 
116 
     | 
    
         | 
| 
       115 
117 
     | 
    
         
             
            宣伝・バグ報告などしてもらえると嬉しいです。
         
     | 
| 
       116 
118 
     | 
    
         | 
| 
      
 119 
     | 
    
         
            +
            ## ac-library-rbを開発したい方向けの情報
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            ### コーディングスタイル
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            Rubocop(Rubyのlintツール)の設定ファイル`.rubocop.yml`は、参考に置いています。  
         
     | 
| 
      
 124 
     | 
    
         
            +
            Rubocopのルールを守ることが必ずしもよくなかったり、ルールを守ることが難しかったりもするので、Rubocopの適用は必須ではないです。  
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            推奨スタイル
         
     | 
| 
      
 127 
     | 
    
         
            +
            - インデントは、半角スペース2文字
         
     | 
| 
      
 128 
     | 
    
         
            +
            - 行末の余計なスペースは削除
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
            ### ディレクトリの説明
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            `lib`ディレクトリ内に各種のデータ構造などのライブラリがあります。  
         
     | 
| 
      
 133 
     | 
    
         
            +
            `lib_lock`は、Gem用にモジュール化させるため`lib`の内容をコピーする形でモジュール化させています。  
         
     | 
| 
      
 134 
     | 
    
         
            +
            `bin/lock_lib.rb`を実行することで、`lib`から`lib_lock`にモジュール化させる形でコピーします。  
         
     | 
| 
      
 135 
     | 
    
         
            +
            なお、`rake`コマンドでテストを実行させると、自動的に`require_relative "./bin/lock_lib.rb"`により、コピーが行われます。  
         
     | 
| 
      
 136 
     | 
    
         
            +
            このあたりはトリッキーで、予定は未定ですが、今後全てモジュール化される等に統一される可能性があります。  
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
       117 
138 
     | 
    
         
             
            ## その他の情報
         
     | 
| 
       118 
139 
     | 
    
         | 
| 
       119 
140 
     | 
    
         
             
            ### RubyのSlackのAtCoderチャンネル
         
     | 
| 
       120 
141 
     | 
    
         | 
| 
       121 
142 
     | 
    
         
             
            [ruby-jp](https://ruby-jp.github.io/) に"atcoder"というチャンネルがあります。
         
     | 
| 
       122 
143 
     | 
    
         | 
| 
      
 144 
     | 
    
         
            +
            ここで、バグ報告などすると、競プロ詳しい人などが反応しやすいかもしれません。
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
       123 
146 
     | 
    
         
             
            Slackに3000人、atcoderチャンネルに250人以上の登録者がいるので、お気軽に参加してください。
         
     | 
| 
       124 
147 
     | 
    
         | 
| 
       125 
148 
     | 
    
         
             
            ### 他言語のライブラリ
         
     | 
    
        data/README.md
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    
    
        data/document_en/lazy_segtree.md
    CHANGED
    
    | 
         @@ -105,13 +105,29 @@ seg.range_apply(l, r, val) 
     | 
|
| 
       105 
105 
     | 
    
         | 
| 
       106 
106 
     | 
    
         
             
            - `O(log n)`
         
     | 
| 
       107 
107 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
            ### max_right 
     | 
| 
      
 108 
     | 
    
         
            +
            ### max_right(l){  } -> Integer
         
     | 
| 
       109 
109 
     | 
    
         | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
      
 110 
     | 
    
         
            +
            It applies binary search on the LazySegtree.
         
     | 
| 
       111 
111 
     | 
    
         | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
      
 112 
     | 
    
         
            +
            **Constraints**
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            - `0 ≦ l ≦ n`
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            **Complexity**
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            - `O(log n)`
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            ### min_left(r){  } -> Integer
         
     | 
| 
       113 
121 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
            It applies binary search on the LazySegtree.
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            **Constraints**
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            - `0 ≦ r ≦ n`
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            **Complexity**
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
            - `O(log n)`
         
     | 
| 
       115 
131 
     | 
    
         | 
| 
       116 
132 
     | 
    
         
             
            ## Verified
         
     | 
| 
       117 
133 
     | 
    
         | 
    
        data/document_en/segtree.md
    CHANGED
    
    | 
         @@ -104,6 +104,14 @@ It returns `op(a[0], ..., a[n - 1])`. 
     | 
|
| 
       104 
104 
     | 
    
         
             
            seg.max_right(l, &f)
         
     | 
| 
       105 
105 
     | 
    
         
             
            ```
         
     | 
| 
       106 
106 
     | 
    
         | 
| 
      
 107 
     | 
    
         
            +
            **Constraints**
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            - `0 ≦ l ≦ n`
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            **Complexity**
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            - `O(log n)`
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
       107 
115 
     | 
    
         
             
            It applies binary search on the segment tree.
         
     | 
| 
       108 
116 
     | 
    
         | 
| 
       109 
117 
     | 
    
         
             
            ### min_left(r, &f) -> Integer
         
     | 
| 
         @@ -114,6 +122,14 @@ seg.min_left(r, &f) 
     | 
|
| 
       114 
122 
     | 
    
         | 
| 
       115 
123 
     | 
    
         
             
            It applies binary search on the segment tree.
         
     | 
| 
       116 
124 
     | 
    
         | 
| 
      
 125 
     | 
    
         
            +
            **Constraints**
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            - `0 ≦ r ≦ n`
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            **Complexity**
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            - `O(log n)`
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
       117 
133 
     | 
    
         
             
            ## Verified
         
     | 
| 
       118 
134 
     | 
    
         | 
| 
       119 
135 
     | 
    
         
             
            - [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
         
     | 
    
        data/document_ja/lazy_segtree.md
    CHANGED
    
    | 
         @@ -8,10 +8,10 @@ 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            ## 特異メソッド
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            ### new(v, e, id 
     | 
| 
      
 11 
     | 
    
         
            +
            ### new(v, e, id){  }
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            ```ruby
         
     | 
| 
       14 
     | 
    
         
            -
            seg = LazySegtree.new(v, e, id 
     | 
| 
      
 14 
     | 
    
         
            +
            seg = LazySegtree.new(v, e, id)
         
     | 
| 
       15 
15 
     | 
    
         
             
            ```
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
            第1引数は、`Integer`または`Array`です。
         
     | 
| 
         @@ -21,8 +21,22 @@ seg = LazySegtree.new(v, e, id, op, mapping, compositon) 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            第2引数`e`は、単位元です。ブロックで二項演算`op(x, y)`を定義することで、モノイドを定義する必要があります。
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            また、インスタンス作成後に、`LazySegtree#set_mapping{ }`と`LazySegment#set_composition{ }`を用い、適切にインスタンス変数にprocを設定する必要があります。
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       24 
26 
     | 
    
         
             
            **計算量** `O(n)`
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
            ### new(v, op, e, mapping, composition, id)
         
     | 
| 
      
 29 
     | 
    
         
            +
            ### new(v, e, id, op, mapping, composition)
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 32 
     | 
    
         
            +
            seg = LazySegtree.new(v, op, e, mapping, compositon, id)
         
     | 
| 
      
 33 
     | 
    
         
            +
            seg = LazySegtree.new(v, e, id, op, mapping, compositon)
         
     | 
| 
      
 34 
     | 
    
         
            +
            ```
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            前者は、本家ライブラリに合わせた引数の順番。  
         
     | 
| 
      
 37 
     | 
    
         
            +
            後者は、procを後ろにまとめた引数の順番で、これは非推奨。  
         
     | 
| 
      
 38 
     | 
    
         
            +
            内部で、第2引数がprocかどうかで、場合分けしています。
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
       26 
40 
     | 
    
         
             
            ## インスタンスメソッド
         
     | 
| 
       27 
41 
     | 
    
         | 
| 
       28 
42 
     | 
    
         
             
            ### set(pos, x)
         
     | 
| 
         @@ -53,7 +67,7 @@ seg.get(pos) 
     | 
|
| 
       53 
67 
     | 
    
         
             
            seg.prod(l, r)
         
     | 
| 
       54 
68 
     | 
    
         
             
            ```
         
     | 
| 
       55 
69 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
            `op(a[l], ..., a[r - 1])`  
     | 
| 
      
 70 
     | 
    
         
            +
            `op(a[l], ..., a[r - 1])` を返します。引数は半開区間です。`l == r`のとき、単位元`e`を返します。
         
     | 
| 
       57 
71 
     | 
    
         | 
| 
       58 
72 
     | 
    
         
             
            **制約** `0 ≦ l ≦ r ≦ n`
         
     | 
| 
       59 
73 
     | 
    
         | 
| 
         @@ -65,19 +79,24 @@ seg.prod(l, r) 
     | 
|
| 
       65 
79 
     | 
    
         
             
            seg.all_prod
         
     | 
| 
       66 
80 
     | 
    
         
             
            ```
         
     | 
| 
       67 
81 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
            `op(a[0], ..., a[n - 1])`  
     | 
| 
      
 82 
     | 
    
         
            +
            `op(a[0], ..., a[n - 1])` を返します。サイズが0のときは、単位元`e`を返します。
         
     | 
| 
       69 
83 
     | 
    
         | 
| 
       70 
84 
     | 
    
         
             
            **計算量** `O(1)`
         
     | 
| 
       71 
85 
     | 
    
         | 
| 
       72 
86 
     | 
    
         
             
            ### apply(pos, val)
         
     | 
| 
      
 87 
     | 
    
         
            +
            ### apply(s, r, val)
         
     | 
| 
       73 
88 
     | 
    
         | 
| 
       74 
89 
     | 
    
         
             
            ```ruby
         
     | 
| 
       75 
90 
     | 
    
         
             
            seg.apply(pos, val)
         
     | 
| 
      
 91 
     | 
    
         
            +
            seg.apply(l, r, val)
         
     | 
| 
       76 
92 
     | 
    
         
             
            ```
         
     | 
| 
       77 
93 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
      
 94 
     | 
    
         
            +
            1. `a[p] = f(a[p])`
         
     | 
| 
      
 95 
     | 
    
         
            +
            2. 半開区間`i = l..r`について`a[i] = f(a[i])`
         
     | 
| 
       79 
96 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
            **制約**  
     | 
| 
      
 97 
     | 
    
         
            +
            **制約** 
         
     | 
| 
      
 98 
     | 
    
         
            +
            1. `0 ≦ pos < n` 
         
     | 
| 
      
 99 
     | 
    
         
            +
            2. `0 ≦ l ≦ r ≦ n`
         
     | 
| 
       81 
100 
     | 
    
         | 
| 
       82 
101 
     | 
    
         
             
            **計算量** `O(log n)`
         
     | 
| 
       83 
102 
     | 
    
         | 
| 
         @@ -87,28 +106,44 @@ seg.apply(pos, val) 
     | 
|
| 
       87 
106 
     | 
    
         
             
            seg.range_apply(l, r, val)
         
     | 
| 
       88 
107 
     | 
    
         
             
            ```
         
     | 
| 
       89 
108 
     | 
    
         | 
| 
      
 109 
     | 
    
         
            +
            3引数の`apply`を呼んだときに、内部で呼ばれるメソッド。  
         
     | 
| 
      
 110 
     | 
    
         
            +
            直接、`range_apply`を呼ぶこともできる。
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
       90 
112 
     | 
    
         
             
            **制約** `0 ≦ l ≦ r ≦ n`
         
     | 
| 
       91 
113 
     | 
    
         | 
| 
       92 
114 
     | 
    
         
             
            **計算量** `O(log n)`
         
     | 
| 
       93 
115 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
            ### max_right
         
     | 
| 
      
 116 
     | 
    
         
            +
            ### max_right(l){  } -> Integer
         
     | 
| 
       95 
117 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
      
 118 
     | 
    
         
            +
            LazySegtree上で、二分探索をします。
         
     | 
| 
       97 
119 
     | 
    
         | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 120 
     | 
    
         
            +
            **制約**  `0 ≦ l ≦ n`
         
     | 
| 
       99 
121 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
            **計算量** `O(log n)`
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            ### min_left(r){  } -> Integer
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            LazySegtree上で、二分探索をします。
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            **制約**  `0 ≦ r ≦ n`
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
            **計算量** `O(log n)`
         
     | 
| 
       101 
131 
     | 
    
         | 
| 
       102 
132 
     | 
    
         
             
            ## Verified
         
     | 
| 
       103 
133 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
            - [AIZU ONLINE JUDGE DSL\_2\_F RMQ and RUQ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F)
         
     | 
| 
       106 
     | 
    
         
            -
            - [AIZU ONLINE JUDGE DSL\_2\_G RSQ and RAQ](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G)
         
     | 
| 
      
 134 
     | 
    
         
            +
            問題のリンクです。Verified済みです。解答はテストコードをご参考ください。
         
     | 
| 
      
 135 
     | 
    
         
            +
            - [AIZU ONLINE JUDGE DSL\_2\_F RMQ and RUQ](ttps://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 
     | 
    
         
            +
            - [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 
     | 
    
         
            +
            - [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 
     | 
    
         
            +
            - [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))
         
     | 
| 
       107 
139 
     | 
    
         | 
| 
       108 
140 
     | 
    
         
             
            以下の問題は、Rubyでは実行時間が厳しくTLEになりACできてないです。
         
     | 
| 
       109 
141 
     | 
    
         
             
            - [ALPC: K \- Range Affine Range Sum](https://atcoder.jp/contests/practice2/tasks/practice2_k)
         
     | 
| 
       110 
142 
     | 
    
         
             
            - [ALPC: L \- Lazy Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_l)
         
     | 
| 
       111 
143 
     | 
    
         | 
| 
      
 144 
     | 
    
         
            +
            下記は、ジャッジにだしてないが、サンプルに正解。`max_right`, `min_left`を使う問題。
         
     | 
| 
      
 145 
     | 
    
         
            +
            - [Quora Programming Challenge 2021: Skyscraper](https://jonathanirvin.gs/files/division2_3d16774b0423.pdf#page=5)
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
       112 
147 
     | 
    
         
             
            ## 参考リンク
         
     | 
| 
       113 
148 
     | 
    
         | 
| 
       114 
149 
     | 
    
         
             
            - 当ライブラリ
         
     | 
| 
         @@ -133,3 +168,10 @@ seg.range_apply(l, r, val) 
     | 
|
| 
       133 
168 
     | 
    
         
             
            ### `ceil_pow2`ではなく、`bit_length`
         
     | 
| 
       134 
169 
     | 
    
         | 
| 
       135 
170 
     | 
    
         
             
            本家C++ライブラリは独自定義の`internal::ceil_pow2`関数を用いてますが、本ライブラリではRuby既存のメソッド`Integer#bit_length`を用いています。そちらの方が計測した結果、高速でした。
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            ## 問題点
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
            ### ミュータブルな単位元
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            本家ACL同様に、初期化の際に配列でも数値でもいいとなっている。  
         
     | 
| 
      
 177 
     | 
    
         
            +
            しかし、数値で要素数を指定した際に、ミュータブルなクラスでも同一オブジェクトで要素を作ってしまっている。
         
     | 
    
        data/document_ja/segtree.md
    CHANGED
    
    | 
         @@ -66,7 +66,7 @@ seg.get(pos) 
     | 
|
| 
       66 
66 
     | 
    
         
             
            seg.prod(l, r)
         
     | 
| 
       67 
67 
     | 
    
         
             
            ```
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
            `op(a[l], ..., a[r - 1])`  
     | 
| 
      
 69 
     | 
    
         
            +
            `op(a[l], ..., a[r - 1])` を返します。引数は半開区間です。`l == r`のとき、単位元`e`を返します。
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
71 
     | 
    
         
             
            **制約**
         
     | 
| 
       72 
72 
     | 
    
         | 
| 
         @@ -82,7 +82,7 @@ seg.prod(l, r) 
     | 
|
| 
       82 
82 
     | 
    
         
             
            seg.all_prod
         
     | 
| 
       83 
83 
     | 
    
         
             
            ```
         
     | 
| 
       84 
84 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
            `op(a[0], ..., a[n - 1])`  
     | 
| 
      
 85 
     | 
    
         
            +
            `op(a[0], ..., a[n - 1])` を返します。空のセグメントツリー、つまりサイズが0のとき、単位元`e`を返します。
         
     | 
| 
       86 
86 
     | 
    
         | 
| 
       87 
87 
     | 
    
         
             
            **計算量**
         
     | 
| 
       88 
88 
     | 
    
         | 
| 
         @@ -96,6 +96,10 @@ seg.max_right(l, &f) 
     | 
|
| 
       96 
96 
     | 
    
         | 
| 
       97 
97 
     | 
    
         
             
            Segtree上で二分探索をします。
         
     | 
| 
       98 
98 
     | 
    
         | 
| 
      
 99 
     | 
    
         
            +
            **制約**  `0 ≦ l ≦ n`
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            **計算量** `O(log n)`
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       99 
103 
     | 
    
         
             
            ### min_left(r, &f) -> Integer
         
     | 
| 
       100 
104 
     | 
    
         | 
| 
       101 
105 
     | 
    
         
             
            ```ruby
         
     | 
| 
         @@ -104,11 +108,15 @@ seg.min_left(r, &f) 
     | 
|
| 
       104 
108 
     | 
    
         | 
| 
       105 
109 
     | 
    
         
             
            Segtree上で二分探索をします。
         
     | 
| 
       106 
110 
     | 
    
         | 
| 
      
 111 
     | 
    
         
            +
            **制約**  `0 ≦ r ≦ n`
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            **計算量** `O(log n)`
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
       107 
115 
     | 
    
         
             
            ## Verified
         
     | 
| 
       108 
116 
     | 
    
         | 
| 
       109 
117 
     | 
    
         
             
            - [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
         
     | 
| 
       110 
118 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
            - [F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
         
     | 
| 
      
 119 
     | 
    
         
            +
            - [ABC185: F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
         
     | 
| 
       112 
120 
     | 
    
         
             
              - xorのセグメントツリーの基本的な典型問題です。FenwickTree(BIT)をxorに改造するだけでも解けます。
         
     | 
| 
       113 
121 
     | 
    
         
             
              - [ACコード(1538ms)](https://atcoder.jp/contests/abc185/submissions/18746817): 通常のSegtree解。
         
     | 
| 
       114 
122 
     | 
    
         
             
              - [ACコード(821ms)](https://atcoder.jp/contests/abc185/submissions/18769200): FenwickTree(BIT)のxor改造版。
         
     | 
    
        data/lib/lazy_segtree.rb
    CHANGED
    
    | 
         @@ -1,17 +1,21 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Segment tree with Lazy propagation
         
     | 
| 
       2 
2 
     | 
    
         
             
            class LazySegtree
         
     | 
| 
       3 
     | 
    
         
            -
              attr_reader 
     | 
| 
      
 3 
     | 
    
         
            +
              attr_reader :d, :lz, :e, :id
         
     | 
| 
       4 
4 
     | 
    
         
             
              attr_accessor :op, :mapping, :composition
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
               
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
              # new(v, op, e, mapping, composition, id)
         
     | 
| 
      
 7 
     | 
    
         
            +
              # new(v, e, id, op, mapping, composition)
         
     | 
| 
      
 8 
     | 
    
         
            +
              # new(v, e, id){ |x, y|  }
         
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize(v, a1, a2, a3 = nil, a4 = nil, a5 = nil, &op_block)
         
     | 
| 
      
 10 
     | 
    
         
            +
                if a1.is_a?(Proc)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @op, @e, @mapping, @composition, @id = a1, a2, a3, a4, a5
         
     | 
| 
      
 12 
     | 
    
         
            +
                else
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @e, @id, @op, @mapping, @composition = a1, a2, a3, a4, a5
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @op ||= op_block
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                v = Array.new(v, @e) if v.is_a?(Integer)
         
     | 
| 
       8 
17 
     | 
    
         | 
| 
       9 
18 
     | 
    
         
             
                @n  = v.size
         
     | 
| 
       10 
     | 
    
         
            -
                @e  = e
         
     | 
| 
       11 
     | 
    
         
            -
                @id = id
         
     | 
| 
       12 
     | 
    
         
            -
                @op = op
         
     | 
| 
       13 
     | 
    
         
            -
                @mapping = mapping
         
     | 
| 
       14 
     | 
    
         
            -
                @composition = composition
         
     | 
| 
       15 
19 
     | 
    
         | 
| 
       16 
20 
     | 
    
         
             
                @log  = (@n - 1).bit_length
         
     | 
| 
       17 
21 
     | 
    
         
             
                @size = 1 << @log
         
     | 
| 
         @@ -22,18 +26,28 @@ class LazySegtree 
     | 
|
| 
       22 
26 
     | 
    
         
             
                (@size - 1).downto(1) { |i| update(i) }
         
     | 
| 
       23 
27 
     | 
    
         
             
              end
         
     | 
| 
       24 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
              def set_mapping(&mapping)
         
     | 
| 
      
 30 
     | 
    
         
            +
                @mapping = mapping
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def set_composition(&composition)
         
     | 
| 
      
 34 
     | 
    
         
            +
                @composition = composition
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       25 
37 
     | 
    
         
             
              def set(pos, x)
         
     | 
| 
       26 
38 
     | 
    
         
             
                pos += @size
         
     | 
| 
       27 
39 
     | 
    
         
             
                @log.downto(1) { |i| push(pos >> i) }
         
     | 
| 
       28 
40 
     | 
    
         
             
                @d[pos] = x
         
     | 
| 
       29 
41 
     | 
    
         
             
                1.upto(@log) { |i| update(pos >> i) }
         
     | 
| 
       30 
42 
     | 
    
         
             
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
              alias []= set
         
     | 
| 
       31 
44 
     | 
    
         | 
| 
       32 
45 
     | 
    
         
             
              def get(pos)
         
     | 
| 
       33 
46 
     | 
    
         
             
                pos += @size
         
     | 
| 
       34 
47 
     | 
    
         
             
                @log.downto(1) { |i| push(pos >> i) }
         
     | 
| 
       35 
48 
     | 
    
         
             
                @d[pos]
         
     | 
| 
       36 
49 
     | 
    
         
             
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
              alias [] get
         
     | 
| 
       37 
51 
     | 
    
         | 
| 
       38 
52 
     | 
    
         
             
              def prod(l, r)
         
     | 
| 
       39 
53 
     | 
    
         
             
                return @e if l == r
         
     | 
| 
         @@ -68,7 +82,11 @@ class LazySegtree 
     | 
|
| 
       68 
82 
     | 
    
         
             
                @d[1]
         
     | 
| 
       69 
83 
     | 
    
         
             
              end
         
     | 
| 
       70 
84 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
               
     | 
| 
      
 85 
     | 
    
         
            +
              # apply(pos, f)
         
     | 
| 
      
 86 
     | 
    
         
            +
              # apply(l, r, f) -> range_apply(l, r, f)
         
     | 
| 
      
 87 
     | 
    
         
            +
              def apply(pos, f, fr = nil)
         
     | 
| 
      
 88 
     | 
    
         
            +
                return range_apply(pos, f, fr) if fr
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       72 
90 
     | 
    
         
             
                pos += @size
         
     | 
| 
       73 
91 
     | 
    
         
             
                @log.downto(1) { |i| push(pos >> i) }
         
     | 
| 
       74 
92 
     | 
    
         
             
                @d[pos] = @mapping.call(f, @d[pos])
         
     | 
| 
         @@ -132,6 +150,35 @@ class LazySegtree 
     | 
|
| 
       132 
150 
     | 
    
         
             
                @n
         
     | 
| 
       133 
151 
     | 
    
         
             
              end
         
     | 
| 
       134 
152 
     | 
    
         | 
| 
      
 153 
     | 
    
         
            +
              def min_left(r, &g)
         
     | 
| 
      
 154 
     | 
    
         
            +
                return 0 if r == 0
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                r += @size
         
     | 
| 
      
 157 
     | 
    
         
            +
                @log.downto(1) { |i| push((r - 1) >> i) }
         
     | 
| 
      
 158 
     | 
    
         
            +
                sm = @e
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                loop do
         
     | 
| 
      
 161 
     | 
    
         
            +
                  r -= 1
         
     | 
| 
      
 162 
     | 
    
         
            +
                  while r > 1 && r.odd?
         
     | 
| 
      
 163 
     | 
    
         
            +
                    r /= 2
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
                  unless g.call(@op.call(@d[r], sm))
         
     | 
| 
      
 166 
     | 
    
         
            +
                    while r < @size
         
     | 
| 
      
 167 
     | 
    
         
            +
                      push(r)
         
     | 
| 
      
 168 
     | 
    
         
            +
                      r = r * 2 + 1
         
     | 
| 
      
 169 
     | 
    
         
            +
                      if g.call(@op.call(@d[r], sm))
         
     | 
| 
      
 170 
     | 
    
         
            +
                        sm = @op.call(@d[r], sm)
         
     | 
| 
      
 171 
     | 
    
         
            +
                        r -= 1
         
     | 
| 
      
 172 
     | 
    
         
            +
                      end
         
     | 
| 
      
 173 
     | 
    
         
            +
                    end
         
     | 
| 
      
 174 
     | 
    
         
            +
                    return r + 1 - @size
         
     | 
| 
      
 175 
     | 
    
         
            +
                  end
         
     | 
| 
      
 176 
     | 
    
         
            +
                  sm = @op.call(@d[r], sm)
         
     | 
| 
      
 177 
     | 
    
         
            +
                  break if (r & -r) == r
         
     | 
| 
      
 178 
     | 
    
         
            +
                end
         
     | 
| 
      
 179 
     | 
    
         
            +
                0
         
     | 
| 
      
 180 
     | 
    
         
            +
              end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
       135 
182 
     | 
    
         
             
              def update(k)
         
     | 
| 
       136 
183 
     | 
    
         
             
                @d[k] = @op.call(@d[2 * k], @d[2 * k + 1])
         
     | 
| 
       137 
184 
     | 
    
         
             
              end
         
     | 
    
        data/lib/segtree.rb
    CHANGED
    
    | 
         @@ -2,21 +2,25 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            class Segtree
         
     | 
| 
       3 
3 
     | 
    
         
             
              attr_reader :d, :op, :n, :leaf_size, :log
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
               
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
      
 5 
     | 
    
         
            +
              # new(e){ |x, y|  }
         
     | 
| 
      
 6 
     | 
    
         
            +
              # new(v, e){ |x, y|  }
         
     | 
| 
      
 7 
     | 
    
         
            +
              # new(v, op, e)
         
     | 
| 
      
 8 
     | 
    
         
            +
              def initialize(a0, a1 = nil, a2 = nil, &block)
         
     | 
| 
      
 9 
     | 
    
         
            +
                if a1.nil?
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @e, @op = a0, proc(&block)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  v = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                elsif a2.nil?
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @e, @op = a1, proc(&block)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  v = (a0.is_a?(Array) ? a0 : [@e] * a0)
         
     | 
| 
      
 15 
     | 
    
         
            +
                else
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @op, @e = a1, a2
         
     | 
| 
      
 17 
     | 
    
         
            +
                  v = (a0.is_a?(Array) ? a0 : [@e] * a0)
         
     | 
| 
       11 
18 
     | 
    
         
             
                end
         
     | 
| 
       12 
19 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                @e  = e
         
     | 
| 
       14 
     | 
    
         
            -
                @op = proc(&block)
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
20 
     | 
    
         
             
                @n = v.size
         
     | 
| 
       17 
21 
     | 
    
         
             
                @log = (@n - 1).bit_length
         
     | 
| 
       18 
22 
     | 
    
         
             
                @leaf_size = 1 << @log
         
     | 
| 
       19 
     | 
    
         
            -
                @d = Array.new(@leaf_size * 2 
     | 
| 
      
 23 
     | 
    
         
            +
                @d = Array.new(@leaf_size * 2, @e)
         
     | 
| 
       20 
24 
     | 
    
         
             
                v.each_with_index { |v_i, i| @d[@leaf_size + i] = v_i }
         
     | 
| 
       21 
25 
     | 
    
         
             
                (@leaf_size - 1).downto(1) { |i| update(i) }
         
     | 
| 
       22 
26 
     | 
    
         
             
              end
         
     | 
| 
         @@ -26,10 +30,12 @@ class Segtree 
     | 
|
| 
       26 
30 
     | 
    
         
             
                @d[q] = x
         
     | 
| 
       27 
31 
     | 
    
         
             
                1.upto(@log) { |i| update(q >> i) }
         
     | 
| 
       28 
32 
     | 
    
         
             
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              alias []= set
         
     | 
| 
       29 
34 
     | 
    
         | 
| 
       30 
35 
     | 
    
         
             
              def get(pos)
         
     | 
| 
       31 
36 
     | 
    
         
             
                @d[@leaf_size + pos]
         
     | 
| 
       32 
37 
     | 
    
         
             
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
              alias [] get
         
     | 
| 
       33 
39 
     | 
    
         | 
| 
       34 
40 
     | 
    
         
             
              def prod(l, r)
         
     | 
| 
       35 
41 
     | 
    
         
             
                return @e if l == r
         
     | 
| 
         @@ -1,18 +1,22 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module AcLibraryRb
         
     | 
| 
       2 
2 
     | 
    
         
             
              # Segment tree with Lazy propagation
         
     | 
| 
       3 
3 
     | 
    
         
             
              class LazySegtree
         
     | 
| 
       4 
     | 
    
         
            -
                attr_reader 
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :d, :lz, :e, :id
         
     | 
| 
       5 
5 
     | 
    
         
             
                attr_accessor :op, :mapping, :composition
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 7 
     | 
    
         
            +
                # new(v, op, e, mapping, composition, id)
         
     | 
| 
      
 8 
     | 
    
         
            +
                # new(v, e, id, op, mapping, composition)
         
     | 
| 
      
 9 
     | 
    
         
            +
                # new(v, e, id){ |x, y|  }
         
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize(v, a1, a2, a3 = nil, a4 = nil, a5 = nil, &op_block)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  if a1.is_a?(Proc)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @op, @e, @mapping, @composition, @id = a1, a2, a3, a4, a5
         
     | 
| 
      
 13 
     | 
    
         
            +
                  else
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @e, @id, @op, @mapping, @composition = a1, a2, a3, a4, a5
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @op ||= op_block
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  v = Array.new(v, @e) if v.is_a?(Integer)
         
     | 
| 
       9 
18 
     | 
    
         | 
| 
       10 
19 
     | 
    
         
             
                  @n  = v.size
         
     | 
| 
       11 
     | 
    
         
            -
                  @e  = e
         
     | 
| 
       12 
     | 
    
         
            -
                  @id = id
         
     | 
| 
       13 
     | 
    
         
            -
                  @op = op
         
     | 
| 
       14 
     | 
    
         
            -
                  @mapping = mapping
         
     | 
| 
       15 
     | 
    
         
            -
                  @composition = composition
         
     | 
| 
       16 
20 
     | 
    
         | 
| 
       17 
21 
     | 
    
         
             
                  @log  = (@n - 1).bit_length
         
     | 
| 
       18 
22 
     | 
    
         
             
                  @size = 1 << @log
         
     | 
| 
         @@ -23,18 +27,28 @@ module AcLibraryRb 
     | 
|
| 
       23 
27 
     | 
    
         
             
                  (@size - 1).downto(1) { |i| update(i) }
         
     | 
| 
       24 
28 
     | 
    
         
             
                end
         
     | 
| 
       25 
29 
     | 
    
         | 
| 
      
 30 
     | 
    
         
            +
                def set_mapping(&mapping)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @mapping = mapping
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def set_composition(&composition)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @composition = composition
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       26 
38 
     | 
    
         
             
                def set(pos, x)
         
     | 
| 
       27 
39 
     | 
    
         
             
                  pos += @size
         
     | 
| 
       28 
40 
     | 
    
         
             
                  @log.downto(1) { |i| push(pos >> i) }
         
     | 
| 
       29 
41 
     | 
    
         
             
                  @d[pos] = x
         
     | 
| 
       30 
42 
     | 
    
         
             
                  1.upto(@log) { |i| update(pos >> i) }
         
     | 
| 
       31 
43 
     | 
    
         
             
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
                alias []= set
         
     | 
| 
       32 
45 
     | 
    
         | 
| 
       33 
46 
     | 
    
         
             
                def get(pos)
         
     | 
| 
       34 
47 
     | 
    
         
             
                  pos += @size
         
     | 
| 
       35 
48 
     | 
    
         
             
                  @log.downto(1) { |i| push(pos >> i) }
         
     | 
| 
       36 
49 
     | 
    
         
             
                  @d[pos]
         
     | 
| 
       37 
50 
     | 
    
         
             
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                alias [] get
         
     | 
| 
       38 
52 
     | 
    
         | 
| 
       39 
53 
     | 
    
         
             
                def prod(l, r)
         
     | 
| 
       40 
54 
     | 
    
         
             
                  return @e if l == r
         
     | 
| 
         @@ -69,7 +83,11 @@ module AcLibraryRb 
     | 
|
| 
       69 
83 
     | 
    
         
             
                  @d[1]
         
     | 
| 
       70 
84 
     | 
    
         
             
                end
         
     | 
| 
       71 
85 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
                 
     | 
| 
      
 86 
     | 
    
         
            +
                # apply(pos, f)
         
     | 
| 
      
 87 
     | 
    
         
            +
                # apply(l, r, f) -> range_apply(l, r, f)
         
     | 
| 
      
 88 
     | 
    
         
            +
                def apply(pos, f, fr = nil)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  return range_apply(pos, f, fr) if fr
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       73 
91 
     | 
    
         
             
                  pos += @size
         
     | 
| 
       74 
92 
     | 
    
         
             
                  @log.downto(1) { |i| push(pos >> i) }
         
     | 
| 
       75 
93 
     | 
    
         
             
                  @d[pos] = @mapping.call(f, @d[pos])
         
     | 
| 
         @@ -133,6 +151,35 @@ module AcLibraryRb 
     | 
|
| 
       133 
151 
     | 
    
         
             
                  @n
         
     | 
| 
       134 
152 
     | 
    
         
             
                end
         
     | 
| 
       135 
153 
     | 
    
         | 
| 
      
 154 
     | 
    
         
            +
                def min_left(r, &g)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  return 0 if r == 0
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  r += @size
         
     | 
| 
      
 158 
     | 
    
         
            +
                  @log.downto(1) { |i| push((r - 1) >> i) }
         
     | 
| 
      
 159 
     | 
    
         
            +
                  sm = @e
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 162 
     | 
    
         
            +
                    r -= 1
         
     | 
| 
      
 163 
     | 
    
         
            +
                    while r > 1 && r.odd?
         
     | 
| 
      
 164 
     | 
    
         
            +
                      r /= 2
         
     | 
| 
      
 165 
     | 
    
         
            +
                    end
         
     | 
| 
      
 166 
     | 
    
         
            +
                    unless g.call(@op.call(@d[r], sm))
         
     | 
| 
      
 167 
     | 
    
         
            +
                      while r < @size
         
     | 
| 
      
 168 
     | 
    
         
            +
                        push(r)
         
     | 
| 
      
 169 
     | 
    
         
            +
                        r = r * 2 + 1
         
     | 
| 
      
 170 
     | 
    
         
            +
                        if g.call(@op.call(@d[r], sm))
         
     | 
| 
      
 171 
     | 
    
         
            +
                          sm = @op.call(@d[r], sm)
         
     | 
| 
      
 172 
     | 
    
         
            +
                          r -= 1
         
     | 
| 
      
 173 
     | 
    
         
            +
                        end
         
     | 
| 
      
 174 
     | 
    
         
            +
                      end
         
     | 
| 
      
 175 
     | 
    
         
            +
                      return r + 1 - @size
         
     | 
| 
      
 176 
     | 
    
         
            +
                    end
         
     | 
| 
      
 177 
     | 
    
         
            +
                    sm = @op.call(@d[r], sm)
         
     | 
| 
      
 178 
     | 
    
         
            +
                    break if (r & -r) == r
         
     | 
| 
      
 179 
     | 
    
         
            +
                  end
         
     | 
| 
      
 180 
     | 
    
         
            +
                  0
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
       136 
183 
     | 
    
         
             
                def update(k)
         
     | 
| 
       137 
184 
     | 
    
         
             
                  @d[k] = @op.call(@d[2 * k], @d[2 * k + 1])
         
     | 
| 
       138 
185 
     | 
    
         
             
                end
         
     | 
| 
         @@ -3,21 +3,25 @@ module AcLibraryRb 
     | 
|
| 
       3 
3 
     | 
    
         
             
              class Segtree
         
     | 
| 
       4 
4 
     | 
    
         
             
                attr_reader :d, :op, :n, :leaf_size, :log
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
      
 6 
     | 
    
         
            +
                # new(e){ |x, y|  }
         
     | 
| 
      
 7 
     | 
    
         
            +
                # new(v, e){ |x, y|  }
         
     | 
| 
      
 8 
     | 
    
         
            +
                # new(v, op, e)
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(a0, a1 = nil, a2 = nil, &block)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  if a1.nil?
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @e, @op = a0, proc(&block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    v = []
         
     | 
| 
      
 13 
     | 
    
         
            +
                  elsif a2.nil?
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @e, @op = a1, proc(&block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    v = (a0.is_a?(Array) ? a0 : [@e] * a0)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  else
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @op, @e = a1, a2
         
     | 
| 
      
 18 
     | 
    
         
            +
                    v = (a0.is_a?(Array) ? a0 : [@e] * a0)
         
     | 
| 
       12 
19 
     | 
    
         
             
                  end
         
     | 
| 
       13 
20 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                  @e  = e
         
     | 
| 
       15 
     | 
    
         
            -
                  @op = proc(&block)
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
21 
     | 
    
         
             
                  @n = v.size
         
     | 
| 
       18 
22 
     | 
    
         
             
                  @log = (@n - 1).bit_length
         
     | 
| 
       19 
23 
     | 
    
         
             
                  @leaf_size = 1 << @log
         
     | 
| 
       20 
     | 
    
         
            -
                  @d = Array.new(@leaf_size * 2 
     | 
| 
      
 24 
     | 
    
         
            +
                  @d = Array.new(@leaf_size * 2, @e)
         
     | 
| 
       21 
25 
     | 
    
         
             
                  v.each_with_index { |v_i, i| @d[@leaf_size + i] = v_i }
         
     | 
| 
       22 
26 
     | 
    
         
             
                  (@leaf_size - 1).downto(1) { |i| update(i) }
         
     | 
| 
       23 
27 
     | 
    
         
             
                end
         
     | 
| 
         @@ -27,10 +31,12 @@ module AcLibraryRb 
     | 
|
| 
       27 
31 
     | 
    
         
             
                  @d[q] = x
         
     | 
| 
       28 
32 
     | 
    
         
             
                  1.upto(@log) { |i| update(q >> i) }
         
     | 
| 
       29 
33 
     | 
    
         
             
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
                alias []= set
         
     | 
| 
       30 
35 
     | 
    
         | 
| 
       31 
36 
     | 
    
         
             
                def get(pos)
         
     | 
| 
       32 
37 
     | 
    
         
             
                  @d[@leaf_size + pos]
         
     | 
| 
       33 
38 
     | 
    
         
             
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                alias [] get
         
     | 
| 
       34 
40 
     | 
    
         | 
| 
       35 
41 
     | 
    
         
             
                def prod(l, r)
         
     | 
| 
       36 
42 
     | 
    
         
             
                  return @e if l == r
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: ac-library-rb
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.5. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.5.2
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - universato
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021-05- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-05-18 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: minitest
         
     |