{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/er-fen-tan-suo-noying-yong/",
    "result": {"data":{"ghostPost":{"id":"Ghost__Post__60fa72003986b000013a3951","title":"二分探索の応用","slug":"er-fen-tan-suo-noying-yong","featured":false,"feature_image":"https://ghost.tech.anti-pattern.co.jp/content/images/2022/04/1_XGofnd5bRfFGPVvXDCnuhg.png","excerpt":"皆さんご存知の二分探索。この応用について今回は書いていきたいと思う。\n\n二分探索の一般化\n二分探索とはつまり、範囲を特定することである。\n\n例億マス計算\nそこで今回は二分探索を使う下記問題を解いていく\n\nC - 億マス計算AtCoder is a programming contest site for anyone from beginners to\nexperts. We hold weekly programming contests online.AtCoderAtCoder Inc.\n[https://atcoder.jp/contests/arc037/tasks/arc037_c]\n\n愚直に2重ループで解くと\n\nO(N²)になるため、時間が足りなくなる\n\nblog-binary_search_2blog-binary_search_2. GitHub Gist: instantly share code,\nnotes, and snippets.Gist262588213843476\n[https://gist.github.com/kooooohe/8cc33e0f1e","custom_excerpt":null,"visibility":"public","created_at_pretty":"23 July, 2021","published_at_pretty":"15 June, 2021","updated_at_pretty":"21 April, 2022","created_at":"2021-07-23T16:38:40.000+09:00","published_at":"2021-06-16T00:00:00.000+09:00","updated_at":"2022-04-21T17:19:32.000+09:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"name":"Kohei Kondo","slug":"kooooohe","bio":null,"profile_image":"https://ghost.tech.anti-pattern.co.jp/content/images/2022/04/MVIMG_20180910_102813.png","twitter":"@kooooohe_","facebook":null,"website":null}],"primary_author":{"name":"Kohei Kondo","slug":"kooooohe","bio":null,"profile_image":"https://ghost.tech.anti-pattern.co.jp/content/images/2022/04/MVIMG_20180910_102813.png","twitter":"@kooooohe_","facebook":null,"website":null},"primary_tag":{"name":"C++","slug":"c","description":null,"feature_image":null,"meta_description":null,"meta_title":null,"visibility":"public"},"tags":[{"name":"C++","slug":"c","description":null,"feature_image":null,"meta_description":null,"meta_title":null,"visibility":"public"},{"name":"algorithm","slug":"algorithm","description":null,"feature_image":null,"meta_description":null,"meta_title":null,"visibility":"public"},{"name":"binary_search","slug":"binary_search","description":null,"feature_image":null,"meta_description":null,"meta_title":null,"visibility":"public"}],"plaintext":"皆さんご存知の二分探索。この応用について今回は書いていきたいと思う。\n\n二分探索の一般化\n二分探索とはつまり、範囲を特定することである。\n\n例億マス計算\nそこで今回は二分探索を使う下記問題を解いていく\n\nC - 億マス計算AtCoder is a programming contest site for anyone from beginners to\nexperts. We hold weekly programming contests online.AtCoderAtCoder Inc.\n[https://atcoder.jp/contests/arc037/tasks/arc037_c]\n\n愚直に2重ループで解くと\n\nO(N²)になるため、時間が足りなくなる\n\nblog-binary_search_2blog-binary_search_2. GitHub Gist: instantly share code,\nnotes, and snippets.Gist262588213843476\n[https://gist.github.com/kooooohe/8cc33e0f1eb035b878db003b0779a71b]#include <algorithm>\n#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nint main() {\n\n  int N, M;\n  cin >> N >> M;\n  vector<long long> a(N);\n  vector<long long> b(N);\n  vector<long long> r(N * N);\n\n  for (int i = 0; i < N; ++i) {\n    cin >> a[i];\n  }\n  for (int i = 0; i < N; ++i) {\n    cin >> b[i];\n  }\n\n  int ind = 0;\n  // O(N)\n  for (int i = 0; i < N; ++i) {\n    // O(N)\n    for (int j = 0; j < N; ++j) {\n      r[ind] = a[i] * b[j];\n      ind++;\n    }\n  }\n  // O(log_N^2)\n  sort(r.begin(), r.end());\n  cout\n\n\n\nこれを 二分探索 in 二分探索でとくと\n\nO(log_(MAX(A)*MAX(B))*N*log_N)\n\nで解けるようになる。\n\n今回、 std:upper_bound を使う。\n\nこれは、指定した数よりも大きい最初のイテレータを返す。これを使用し、x以下の個数を求めることができる。\n\n※内部で二分探索を使用している\n\n> 詳細はこちら https://cpprefjp.github.io/reference/algorithm/upper_bound.html\nstd:upper_bound とstd:lower_boundの使い方は下記がわかりやすい\n\n\n\nlower_boundとupper_boundの使い方 - Qiita1.lower_boundとupper_bound\nlower_boundとupper_boundはC++のSTLライブラリの関数なのじゃ… 俗に言う二分探索に似たやつなのじゃ… 違いとしては\nlower_boundは...Qiitaganyariya\n[https://qiita.com/ganyariya/items/33f1326154b85db465c3]\n\n考え方ざっくり\n\n * 掛け算した結果をもとに二分探索する(外側)\n * ↑の結果をa[i]で割った数値以下の数値を二分探索で探し、カウントする\n\nblog-binary_searchblog-binary_search. GitHub Gist: instantly share code, notes,\nand snippets.Gist262588213843476\n[https://gist.github.com/kooooohe/01db8a05584db938eb8e2e9f52e4e743]\n\n#include <algorithm>\n#include <iostream>\n#include <vector>\n \nusing namespace std;\n \nconst long long INF = 1LL << 60;\nint main() {\n \n  int N, M;\n  cin >> N >> M;\n  vector<long long> a(N);\n  vector<long long> b(N);\n \n  for (int i = 0; i < N; ++i) {\n    cin >> a[i];\n  }\n  for (int i = 0; i < N; ++i) {\n    cin >> b[i];\n  }\n  // O(log_N)\n  sort(b.begin(), b.end());\n \n  long long left = 0;\n  long long right = INF;\n \n  // O(log_(MAX(A)*MAX(B)))\n  while (right - left > 1) {\n    long long mid = (right + left) / 2;\n    long long cnt = 0;\n    // O(N)\n    for (int i = 0; i < N; ++i) {\n      // O(log_N)\n      cnt += upper_bound(b.begin(), b.end(), mid / a[i]) - b.begin();\n    }\n    if (cnt >= M) {\n      right = mid;\n    } else {\n      left = mid;\n    }\n  }\n \n  cout << right << endl;\n}","html":"<p>皆さんご存知の二分探索。この応用について今回は書いていきたいと思う。</p><h4 id=\"%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2%E3%81%AE%E4%B8%80%E8%88%AC%E5%8C%96\">二分探索の一般化</h4><p>二分探索とはつまり、範囲を特定することである。</p><figure class=\"kg-card kg-image-card kg-card-hascaption\"><img src=\"https://cdn-images-1.medium.com/max/800/1*XGofnd5bRfFGPVvXDCnuhg.png\" class=\"kg-image\" alt loading=\"lazy\"><figcaption>例</figcaption></figure><h4 id=\"%E5%84%84%E3%83%9E%E3%82%B9%E8%A8%88%E7%AE%97\">億マス計算</h4><p>そこで今回は二分探索を使う下記問題を解いていく</p><figure class=\"kg-card kg-bookmark-card\"><a class=\"kg-bookmark-container\" href=\"https://atcoder.jp/contests/arc037/tasks/arc037_c\"><div class=\"kg-bookmark-content\"><div class=\"kg-bookmark-title\">C - 億マス計算</div><div class=\"kg-bookmark-description\">AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.</div><div class=\"kg-bookmark-metadata\"><img class=\"kg-bookmark-icon\" src=\"https://img.atcoder.jp/assets/atcoder.png\"><span class=\"kg-bookmark-author\">AtCoder</span><span class=\"kg-bookmark-publisher\">AtCoder Inc.</span></div></div><div class=\"kg-bookmark-thumbnail\"><img src=\"https://img.atcoder.jp/assets/atcoder.png\"></div></a></figure><p></p><p>愚直に2重ループで解くと</p><p>O(N²)になるため、時間が足りなくなる</p><figure class=\"kg-card kg-bookmark-card\"><a class=\"kg-bookmark-container\" href=\"https://gist.github.com/kooooohe/8cc33e0f1eb035b878db003b0779a71b\"><div class=\"kg-bookmark-content\"><div class=\"kg-bookmark-title\">blog-binary_search_2</div><div class=\"kg-bookmark-description\">blog-binary_search_2. GitHub Gist: instantly share code, notes, and snippets.</div><div class=\"kg-bookmark-metadata\"><img class=\"kg-bookmark-icon\" src=\"https://github.githubassets.com/favicons/favicon.svg\"><span class=\"kg-bookmark-author\">Gist</span><span class=\"kg-bookmark-publisher\">262588213843476</span></div></div><div class=\"kg-bookmark-thumbnail\"><img src=\"https://github.githubassets.com/images/modules/gists/gist-og-image.png\"></div></a></figure><!--kg-card-begin: markdown--><pre><code class=\"language-c\">#include &lt;algorithm&gt;\n#include &lt;iostream&gt;\n#include &lt;vector&gt;\n\nusing namespace std;\n\nint main() {\n\n  int N, M;\n  cin &gt;&gt; N &gt;&gt; M;\n  vector&lt;long long&gt; a(N);\n  vector&lt;long long&gt; b(N);\n  vector&lt;long long&gt; r(N * N);\n\n  for (int i = 0; i &lt; N; ++i) {\n    cin &gt;&gt; a[i];\n  }\n  for (int i = 0; i &lt; N; ++i) {\n    cin &gt;&gt; b[i];\n  }\n\n  int ind = 0;\n  // O(N)\n  for (int i = 0; i &lt; N; ++i) {\n    // O(N)\n    for (int j = 0; j &lt; N; ++j) {\n      r[ind] = a[i] * b[j];\n      ind++;\n    }\n  }\n  // O(log_N^2)\n  sort(r.begin(), r.end());\n  cout\n\n</code></pre>\n<!--kg-card-end: markdown--><p>これを 二分探索 in 二分探索でとくと</p><p>O(log_(MAX(A)*MAX(B))*N*log_N)</p><p>で解けるようになる。</p><p>今回、 <code>std:upper_bound を使う。</code></p><p>これは、指定した数よりも大きい最初のイテレータを返す。これを使用し、x以下の個数を求めることができる。</p><p>※内部で二分探索を使用している</p><blockquote><em>詳細はこちら </em><a href=\"https://cpprefjp.github.io/reference/algorithm/upper_bound.html\" rel=\"nofollow noopener noopener\"><em>https://cpprefjp.github.io/reference/algorithm/upper_bound.html</em></a></blockquote><p>std:upper_bound とstd:lower_boundの使い方は下記がわかりやすい</p><p></p><figure class=\"kg-card kg-bookmark-card\"><a class=\"kg-bookmark-container\" href=\"https://qiita.com/ganyariya/items/33f1326154b85db465c3\"><div class=\"kg-bookmark-content\"><div class=\"kg-bookmark-title\">lower_boundとupper_boundの使い方 - Qiita</div><div class=\"kg-bookmark-description\">1.lower_boundとupper_bound lower_boundとupper_boundはC++のSTLライブラリの関数なのじゃ… 俗に言う二分探索に似たやつなのじゃ… 違いとしては lower_boundは...</div><div class=\"kg-bookmark-metadata\"><img class=\"kg-bookmark-icon\" src=\"https://cdn.qiita.com/assets/favicons/public/apple-touch-icon-ec5ba42a24ae923f16825592efdc356f.png\"><span class=\"kg-bookmark-author\">Qiita</span><span class=\"kg-bookmark-publisher\">ganyariya</span></div></div><div class=\"kg-bookmark-thumbnail\"><img src=\"https://qiita-user-contents.imgix.net/https%3A%2F%2Fcdn.qiita.com%2Fassets%2Fpublic%2Farticle-ogp-background-1150d8b18a7c15795b701a55ae908f94.png?ixlib&#x3D;rb-4.0.0&amp;w&#x3D;1200&amp;mark64&#x3D;aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTg0MCZoPTM4MCZ0eHQ2ND1iRzkzWlhKZlltOTFibVRqZ2FoMWNIQmxjbDlpYjNWdVpPT0JydVM5di1PQmhPYVd1USZ0eHQtY29sb3I9JTIzMzMzJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTU0JnR4dC1jbGlwPWVsbGlwc2lzJnR4dC1hbGlnbj1jZW50ZXIlMkNtaWRkbGUmcz0wYmQzOTVjYjVmM2RiMDI1NTE4MWRlYTVjOTBjY2VkYQ&amp;mark-align&#x3D;center%2Cmiddle&amp;blend64&#x3D;aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTg0MCZoPTUwMCZ0eHQ2ND1RR2RoYm5saGNtbDVZUSZ0eHQtY29sb3I9JTIzMzMzJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTQ1JnR4dC1hbGlnbj1yaWdodCUyQ2JvdHRvbSZzPTI2OGQ5YzdmODQyNTRiZTdlMmVkNjYzMzQxZjkyZDJi&amp;blend-align&#x3D;center%2Cmiddle&amp;blend-mode&#x3D;normal&amp;s&#x3D;1cfe7c9b2e2e53217e7d3758970d013c\"></div></a></figure><p></p><p>考え方ざっくり</p><ul><li>掛け算した結果をもとに二分探索する(外側)</li><li>↑の結果をa[i]で割った数値以下の数値を二分探索で探し、カウントする</li></ul><figure class=\"kg-card kg-bookmark-card\"><a class=\"kg-bookmark-container\" href=\"https://gist.github.com/kooooohe/01db8a05584db938eb8e2e9f52e4e743\"><div class=\"kg-bookmark-content\"><div class=\"kg-bookmark-title\">blog-binary_search</div><div class=\"kg-bookmark-description\">blog-binary_search. GitHub Gist: instantly share code, notes, and snippets.</div><div class=\"kg-bookmark-metadata\"><img class=\"kg-bookmark-icon\" src=\"https://github.githubassets.com/favicons/favicon.svg\"><span class=\"kg-bookmark-author\">Gist</span><span class=\"kg-bookmark-publisher\">262588213843476</span></div></div><div class=\"kg-bookmark-thumbnail\"><img src=\"https://github.githubassets.com/images/modules/gists/gist-og-image.png\"></div></a></figure><p></p><!--kg-card-begin: markdown--><pre><code class=\"language-cpp\">#include &lt;algorithm&gt;\n#include &lt;iostream&gt;\n#include &lt;vector&gt;\n \nusing namespace std;\n \nconst long long INF = 1LL &lt;&lt; 60;\nint main() {\n \n  int N, M;\n  cin &gt;&gt; N &gt;&gt; M;\n  vector&lt;long long&gt; a(N);\n  vector&lt;long long&gt; b(N);\n \n  for (int i = 0; i &lt; N; ++i) {\n    cin &gt;&gt; a[i];\n  }\n  for (int i = 0; i &lt; N; ++i) {\n    cin &gt;&gt; b[i];\n  }\n  // O(log_N)\n  sort(b.begin(), b.end());\n \n  long long left = 0;\n  long long right = INF;\n \n  // O(log_(MAX(A)*MAX(B)))\n  while (right - left &gt; 1) {\n    long long mid = (right + left) / 2;\n    long long cnt = 0;\n    // O(N)\n    for (int i = 0; i &lt; N; ++i) {\n      // O(log_N)\n      cnt += upper_bound(b.begin(), b.end(), mid / a[i]) - b.begin();\n    }\n    if (cnt &gt;= M) {\n      right = mid;\n    } else {\n      left = mid;\n    }\n  }\n \n  cout &lt;&lt; right &lt;&lt; endl;\n}\n</code></pre>\n<!--kg-card-end: markdown-->","url":"https://ghost.tech.anti-pattern.co.jp/er-fen-tan-suo-noying-yong/","canonical_url":null,"uuid":"927c333b-b084-4adc-837c-1e881c94bb26","page":null,"codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"60fa72003986b000013a3951","reading_time":3}},"pageContext":{"slug":"er-fen-tan-suo-noying-yong"}},
    "staticQueryHashes": ["176528973","2358152166","2561578252","2731221146","4145280475"]}