前提・実現したいこと
こんにちは。
現在、こちらの問題を解いています。
そこで、実行時間制限超過のエラーが出てしまっているので、直したいと考えています。
ソースコード
こちらの問題を解いていて、コードを以下のように書きました。
C++
1#include <bits/stdc++.h> 2 3using namespace std; 4 5int main() { 6 int N, Q; 7 cin >> N >> Q; 8 vector<int> a(N); 9 vector<int> x(Q); 10 11 int count=0; 12 13 for (int i=0; i<N; i++) { 14 cin >> a.at(i); 15 } 16 for (int i=0; i<Q; i++) { 17 cin >> x.at(i); 18 } 19 20 sort(a.begin(), a.end()); 21 for (int i=0; i<Q; i++) { 22 for (int j=0; j<N; j++) { 23 if (a.at(j) >= x.at(i)) { 24 count++; 25 } 26 if (j == N-1) { 27 cout << count << endl; 28 count = 0; 29 } 30 } 31 } 32}
発生している問題
上記のコードを提出すると、TLE(実行時間制限超過)
と表示されてしまいます。
恐らく、二重ループを使用しているところで計算量が大きくなってしまっているため、エラーが発生しているのではないかと思っております。
しかしながら、二重ループ以外で、どう書き換えればいいのかが分かりません。
ざっくりとした質問になってしまいましたが、ご教授いただけると幸いです。
よろしくお願い致します。
二重ループで最大で10^9 × 10^9 してるので現実的ではないですね。
線形探索では厳しいと思います。
https://atcoder.jp/contests/abc231/editorial/3074
公式解説が既にあるのでご覧になるとよいかと思います。
ソートした配列に対して二分探索することでxより大きくなる要素番号を見つけ、Nからその要素番号を引いてますね。
https://atcoder.jp/contests/abc231/editorial/3075
さらにもう1つの解説動画でクエリ(xの配列)のソートをしてます。
具体的な処理は見ていませんが、恐らく二分探索の範囲を徐々に狭め探索回数の軽減につなげているではないかと思います。
Crimson_Tide様
公式解説の更に詳しい解説、ありがとうございます。
二分探索が少し苦手なため、今まで避けてきていたのですが、
この機会に正面から向き合ってみようと思います!
ありがとうございます。
> https://atcoder.jp/contests/abc231/editorial/3075
> さらにもう1つの解説動画でクエリ(xの配列)のソートをしてます。
> 具体的な処理は見ていませんが、恐らく二分探索の範囲を徐々に狭め探索回数の軽減につなげているで
> はないかと思います。
ホントにこっちの方が速いか疑わしい...二分検索してないっポいし。
回答2件
あなたの回答
tips
プレビュー