制限時間:3秒
スペースの制約:262144K
連続勧告効果を最適化するために、見出しの今日は、毎日大量のデータを保存して処理します。シナリオを考えてみましょう:私たちは自分の時間に応じて、ユーザーを登録し、各ユーザーが別のプリファレンス値を持っている、記事のクラスのために、ラベルに来ている、我々は、一定の期間内に登録されたユーザについて知りたいと思うでしょう(付属のラベルをバッチユーザ)、Kそのような物品の好みの値のためのユーザの数。いくつかの特別な理由であるため、完全にユーザの範囲をカバーしないであろうクエリが別のユーザの間隔(L1無し<= L2 <= R2 <= R1)問い合わせます。
説明を入力します。
入力:nは整数n個の第1のユーザの行動第二行の数を表し、i番目iはユーザを表す特定の物品3の動作の優先度のクエリ行4 Qを表す正の整数のユーザセット番号第(3 + Q)行に、三つの整数Lを含む各行は、R、K、すなわち、<=は、I <= rは、ユーザの好みにユーザkの値は、そのような物品符号L参照、クエリの集合を表します番号。データ= 300000 <Nの範囲であり、q <= 300000 kは整数であります
出力説明:
出力:Qの行の合計は、それぞれの行は番号kのユーザ選好値の整数を表します。
入力例1:
5 1 2 3 3 5 3 1 2 1 2 4 3 5 3
出力例1:
1 0 2
例1:
サンプルの説明: 5人のユーザが嗜好値が、それぞれ1,2,3,3,5、である、ある 参照用の質問の最初のセット[2]ユーザ1のユーザ嗜好の数が1である 第チャレンジの基準セットに対して[2,4]ユーザ5のユーザ嗜好の値は数0である [3,5]ユーザ3のユーザ嗜好の値は数2であるクエリの数の第三の組の
問題解決のアイデア:
ただ、タイトルを見始めて、それは、クエリ間隔の対象であるため、以前のk値を見つけることが見出されたものは、状態として保存することはできませんセグメントツリー、RMQしたいと思います。見つけるために使用される技術の約半分しか見つかった問題の解決策を検索、理解するためにチャートを見てみましょう。
バイナリサーチのために、私たちは一種の値のようなものでしたが、ラベルも一緒にソートする必要がありますので、クエリ間隔があることを指摘しました。また、昇順に配置された参照断片に等しい優先値は、このような構造は、書き込み(NUMと呼ぶ)と比較関数を書き換えることができることに留意されたいです。だから、昇順で数字の後に、我々はR、あなたが[2,6]の値の好みの範囲で検索したい場合は、数2は、L = 2 =上限2及びkは、= 2のみ二分探索k個を必要としていることを見ることができます6 =下限。
(また、間隔は、バイナリ検索はLとRを位置決めする第二分探索kとして理解され、そしてあなたは、アレイの行に比較関数を使用することができるならば、長さを選択し、実際にすべてのソート関数の後、ライン上の2つだけのバイナリ検索を必要とすることができます彼らはすべてのカスタム比較関数を使用するための良好なため、同じ)は、境界線を見つけるためにのみ、バイナリサーチ一度使用することができます
図4は、下限および6上限見つけ、上限と下限との間の長さは、[2,6]の間の優先、すなわち、答えは2であり、数2です。
バイナリ機能が探している使用する必要があり、ここでのレビューです:
lower_bound
、最初のポイントの位置が左以上で見つけます
upper_bound
最後の点の右端以下突き止めます
音符が見出された:次いで、過ごすために2,4のインデックスを見つけるために、例えば、2 = 4-2以下の比較機能を使用する場合、添字3,4が見つかりません。添字比較的等号、その後、ANSR-ansL + 1が、間違った理由から提出されたこのようなプログラムに参加しようとした後発見される......
1つの#include <iostreamの> 2の#include <cstdioを> 3。の#include <アルゴリズム> 4。 使用した 名前空間STD; 5 6。 のconst int型 MAXN = 300000 + 5。 、 。7 。8 ストラクト{numは 9。 int型のID; 10 int型のVal、 11 BOOLの 演算子 < (CONST民&B)をCONST { 12は、 IF(ヴァル== b.val)戻り ID < b.id; //ノートが間違ってサインに等しい 13である 他の 戻りヴァル< b.val。 14 } 15 } NUM [MAXN]。 16 17 のint main()の 18 { 19 INT N。 20 のscanf(" %d個"、&N) 21 のためには、(int型 = Iを0 ; iがn <; iは++ ){ 22 のscanf(" %dの"、およびNUM [I] .val)。 23 NUM [I] .ID = I。 24 } 25 ソート(NUM、NUM + N)。 26 int型Q; 27 scanf関数(" %のD "、&Q)。 28 一方(q-- ){ 29 のint L、R、K。 30 のscanf(" %D%D%D "、&L&R&K)。 31 l--。r--の; 32 民L、R。 33 L.id = L。R.id = R。 34 L.val = R.val = K。 35 INT ansL = LOWER_BOUND(NUM、NUM + N、L) - NUM。 36 INT ANSR = UPPER_BOUND(NUM、NUM + N、R) - NUM。 37 のprintf(" %d個の\ n "、Ansri- Ansla)。 38 } 39 40 戻り 0 ; 41 }