O(N ^ 2)アプローチの考えを始め、最初のソートXとシーケンシャル列挙アップ正方形に上下長さに関係なく限界まで保持することができるどのように多くの点(つまり、見るために前方最大点をX、最初について検討制限)。これらの点は、それが再び似てやります。。(そしてそうの気持ちを言う方法23333のO(N ^ 2 logN個)まで)。
これはデータが大きすぎる、確かではありません。しかし、いずれにせよ、我々はいくつかの最適化を行う必要があります。
私たちは、Y現像液の座標何制限するプロセスを最適化することができるかどうか、プロセスの周りに境界を制限する権利を留保します。
私は縦座標た場合、境界上のi番目のリーフノードに代わって左から右へ、ツリーラインを考えてみましょう、この時点で答えが(右の境界が風雲ので、列挙右の過程で常にあることに注意してどのくらいですセグメントツリーは絶えず)変化しています。
明らかに、点yの縦軸を添加した後、第二のリーフにY + Y答えが+1 k個であろう;穿刺点とその逆。
だから我々は、最大セグメントツリー&アップデートがそれに答える維持するために、xが再び単調なスイープの座標側掃引側を並べ替えます。
ツリーラインのリーフノード2 * 10 ^ 9はるかがあります。しかし、今はほとんど問題があります。
その後、直接多くの葉の境に関わる書き込み、その動的セグメントツリーの処方箋はオフにする必要があります。しかし、我々は、アルゴリズムの少ない空間と時間の複雑さは、それが離散することができるかどうかを検討したいですか?
例えば、質問は、我々はそれが縦をカバーするために任意のY [i]とY [i]が+ Kなかったと言う:これはあまりにも多くのツリーラインあなたはそれがその妥当性を証明しなければならない、離散したいように葉空のポイント、残りは空でないポイントです。個別のケースならば、我々は最後の答えにデフォルト設定されます非空のポイントを取るための場所でなければなりません。実際には、実際にそうである、それは、最も近い空でない点の両側に+1からそれまでの範囲をカバーする場合、空の点を考慮して確実に覆われる。範囲は間隔+1 -1可能などの単語の前に撤回されました、そう考えていません。
あなたはACと非常に快適にすることができるようにまあ、コードも非常によく書かれています。
#include <ビット/ STDC ++ H> の#defineは長い長いllの 名前空間stdを使用します。 const int型N = 100005; (<< 1 O)の#define LC の#define中間(L + R >> 1) の#define RC((O << 1)| 1) インラインint型リード(){ int型のx = 0。チャーCH = GETCHAR()。 用(;!isdigit(CH); CH = getchar関数()); 用(; isdigit(CH)、CH = GETCHAR())X = X * 10 + CH-'0' 。 Xを返します。 } 構造体ノード{ int型のX、Y、Z。 ブール演算子<(constのノード&U)のconst { UX X <返します。 } } [N]。 INTのN、K、NUM [N * 2]、KY、ANS、W。 INT MX [N * 8 + 1]、タグ[N * 8 + 1]、LE、RI。 インラインボイド(O INT、INT広告){タグ[O] + =広告、MX [O] + =広告;}取得します インラインボイドプッシュダウン(INT O){取得(LC、タグ[O])は、Get(RC、タグ[O])、タグ[O] = 0;} ボイド更新(INT 0、int型のL、int型R){ もし(L> =ル&& R <= RI){取得(O、W)。返す;} プッシュダウン(O) もし(LE <= MID)更新(LC、L、MID)。 IF(RI> MID)アップデート(RC、ミッド+ 1、R)。 MX [O] = MAX(MX [LC]、MX [RC])。 } インラインボイドは(){解決 ソート(A + 1、A + N + 1)。 以下のために(INT i = 1; iは= N <; iは++)NUMを[++ KY]は[i]を.Y、numは[++ KY]が[I] .Z ==します。 ソート(NUM + 1、NUM + KY + 1)、KY =ユニーク(NUM + 1、NUM + KY + 1)-num-1。 以下のために(INT i = 1; iが<= N; iは++){ [I] .Y = LOWER_BOUND(NUM + 1、NUM + KY + 1を、[I] .Y)-num。 [I] .Z = LOWER_BOUND(NUM + 1、NUM + KY + 1、[I] .Z)-num。 } {ため(ANS = MAX(ANS、MX [1])、iは++; iは= N <I = 1、L 1は= INT) ([I] .xa [L] .X> K)LEは、[L] .Y、RI = A [L] .Z、W = -1、更新(1,1、KY)、L ++ =つつ。 LEは= [I] .Y、RI = [I] .Z 1、更新(1,1、KY)= W。 } } int型のmain(){ N =)(読み取り、K =リード()。 (私は++; iが<= n iは1 = INT)のための [I] .X = read()は、[I] .Y = read()は、[I] .Z = [I]・Y + K; ()のprintf( "%d個の\ n"、ANS)を解きます。 0を返します。 }