長い時間は、ブログの水を書いていない,,,
Darkraftの世界:アザトースのための戦い
トピックリンク:https://codeforces.com/contest/1320/problem/C
質問の意味: 武器のN数があり、それぞれの武器はその価格を持って、Mシールドが存在し、各シールドは、その価格を持っている Kモンスターが存在し、それぞれのモンスターの攻撃は、X、Yのための防衛力は、奇妙なを殺すですZに金貨を落ちた後 、我々は選択した場合、武器は力が西より大きく、攻撃、そして我々は、シールド防御力を選んだ李よりも大きい場合、我々は紫の金貨を得ることができます 私たちは私たちに利用できるように、武器や盾を選び、選択しなければならないことを要求最大トータル・リターン・分析: シールドはB(価格CB)で、我々は(価格CA)のための武器を選択したと仮定 金の合計と私たちは利益を得ることができ、我々はモンスターがドロップ殺すことができます-武器の価格を-シールド価格- CA - CB ANS =利用可能金貨とある:まず、前処理工程①、ソート武器の、次に列挙武器②、Xモンスターの順序に従って③、重みツリーライン:防衛のためのインデックス値、すなわち、 [L、R] [防御値L、防御R]を表す硬貨に対応する添字値、すなわちツリー[L] = 10は、シールドはL防御利用可能な金と10であるときことを示し、我々はオープン、同様アレイ、前記〔I〕手段その武器の攻撃力I グリッド
プロセスを開始する前に、我々は、我々は属性値C配列を持つモンスターXで武器、モンスターソートをソート
私は武器を表し、jは怪物を表して-私たちは二重のポインタを使用する<i、jは>プロセスに
第二に、演算処理の答え:
①、私たちは私に列挙し、jが、私たちはこのモンスターの攻撃力はあまり私よりある判断
であればそれほどI(C [J] .X <より、② i)は、 私たちが防衛シールドを選択した場合大きいC [J] .Y、金貨よりも、我々はそれに加えて、C [j]が.Zを取得できませんでしたか?
言い換えれば、私たちの現在の武器はI、および長期防衛がcよりも大きいと[J] .Yとしてシールド、金の盾が利用可能であり、あなたは、cをカウントすることができます[J] .Z
③、もちろん、だけでなく、購入盾ので、 、その最大の利益-私たちは買うためのお金を、シールドが最大(価格のシールド可能な金と盾)でなければなりません
①②③対応するコード
以下のために(INT iが= 1 ; I <= N; I ++ ) { 一方、(J <= K && C [J] .X < I) { //は防御力はC [J]をカウントすることができる利用可能なトータルリターンシールド.Y C [J]より大きい表す.Z update_range(C [J] .Y + 1 、N末端、C [POS] .Z) J ++ ; } 年 = MAX(年ツリー[ 1 ] .maxn - [I]); }
いくつかの詳細は、(怠け者言いません-.-
#include <ビット/ STDC ++ H> の#define担当者(I、N)のための(iは= INT; I <= N; I ++) の#define iがN =(INTのための(I、N)ごとに、 I> =; i--) の#define LL、長い長い の#define長いlong int型 使用して 名前空間はstdを、 CONST LL INF(0x3f3f3f3f3f3f3f3fll)。 const int型 INF(0x3f3f3f3f )。 CONST INT N = 1E6 + 150 。 int型 [N]、B [N]、N、M、K、TOT、MI1 = INF、MI2 = INF。 構造体の木 { LL L、R、怠惰、MAXN。 }ツリー[N << 2 ]。 空push_up(LL RT) { ツリー[RT] .maxn = MAX(ツリー[RT << 1 ] .maxn、ツリー[RT << 1 | 1 ] .maxn)。 } 空push_down(RT -1,11,11-長) { もし(ツリー[RT] .lazy) { ツリー[RT << 1 ] .lazy + = ツリー[RT] .lazy。 ツリー[RT << 1 | 1 ] .lazy + = ツリー[RT] .lazy。 ツリー[RT << 1 ] .maxn + = ツリー[RT] .lazy。 ツリー[RT << 1 | 1 ] .maxn + = ツリー[RT] .lazy。 [RT] .lazyツリー = 0 。 } } 空のビルド(LL、L、LL R、LL RT) { [RT] .lazyツリー = 0、ツリー[RT] .L = L、木[RT] .R = R。 もし(L == R) { ツリー[RT] .maxn = - B [L]。 リターン; } LL半ば =(L + R)>> 1 。 ビルド(リットル、ミッド、RT << 1 )。 ビルド(ミッド + 1、R、RT << 1 | 1 ); push_up(RT)。 } 空update_range(LL、L、LL R、LLキー、LL RT) { もし(ツリー[RT] .R <L ||ツリー[RT] .L> R) のリターン; もし(L <=ツリー[RT] .L && R> = ツリー[RT] .R) { ツリー[RT] .maxn + = キー。 [RT] .lazyツリー + = キー。 リターン; } push_down(RT、ツリー[RT]・R -ツリー[RT] .L + 1 )。 LL半ば =(ツリー[RT]・R +ツリー[RT] .L)>> 1 。 もし(L <= 中旬) update_range(L、R、キー、RT << 1 )。 もし(R> 中旬) update_range(L、R、キー、室温 << 1 | 1 ); push_up(RT)。 } 構造体ノード{ int型X、Y、Z。 ブール 演算子 <(CONSTノード&)のconst { リターン X < 斧。 } } C [N]。 主符号付き() { scanf関数(" %LLD%LLD%LLD "、&N、&M、およびK); 担当者(I、1 、N) { int型のPOS、ヴァル。 scanf関数(" %LLD%LLD "、&POS、&val)で、 もし [POS] =([POS]!)のval; 他 [POS] = 分([POS]、ヴァル)。 MI1 =分(MI1、ヴァル)、TOT = (POSに)MAX。 } 担当者(I、1 、m)と { int型のPOS、ヴァル。 scanf関数(" %LLD%LLD "、&POS、&val)で、 もし(!B [POS])B [POS] = valの; 他の B [POS] = 分(B [POS]、ヴァル)。 MI2 = 分(MI2、ヴァル)。 } N = 0 。 用(とN - 10、1 ) { もし(!B [i])とB [I] = B [I + 1 ]。 そう であれば(B [I + 1 ])B [I] =分(B [I]、B [I + 1 ])。 もし(!B [i]は&& N)= I。 } 担当者(I、1、K)のscanf(" %LLD%LLD%LLD "、&C [i]は.X、&C [i]は.Y、&C [i]の.Z)。 ソート(C + 1、C + 1 + K)。 int型 ANS = -mi1 - MI2、J = 1 ; ビルド(1、nは、1 )。 受信(および1 、しかし) { 場合([i])と { 一方、(J <= K && C [J] .X < I) { update_range(C [J]・Y + 1、N、C [j]は.Z、1 )。 J ++ ; } 年 = MAX(年ツリー[ 1 ] .maxn - [I]); } } printf(" %のLLD \ n " 、ANS)。 リターン 0 ; }