(牛離れゲームはデカルト木を持っている、すべてのゲームは、デカルト木...自閉症、富栄のTi経験を使用しません)
トピックリンクします。https://ac.nowcoder.com/acm/contest/884/C
問題の意味:二つの配列、B所与は、最大値を見つける{分[L、R] *和B [L、R]}
より多くの明白なアプローチは、セグメントツリー/ STテーブルのメンテナンスで最高値の範囲ですが、(zkwセグメントツリーがあったことができます)、カードにnlogn実際、多くの場合、簡単ですが、レース制限時間が3秒を上げたときに、よく基本的に書きました
直接最小間隔/添字大きな値を維持し、その後、最小([I] <0分最大治療を見つけるために)最小/最大および左接頭辞で最小値を見つけるために、最小から回答を計算開始右側もプレフィックス最小/最大値を検索し、回答一度計算、2つの部分に分割分割線として最小値を計算していき
LOGNセグメントツリークエリ効率、全体的な複雑性O(nlogn)、STの前処理nlognテーブル、全体的な複雑さは、O(nlogn)と大きい定数であり、不滅とゲームも研究、O(n)のアプローチを発見した後にはい、それはデカルト木の魔法で、見て
それがあるので、私たちは、最小で、その後、私たちはデカルト木アレイ上に構築小さな...回のオーダーを見つけ、そのプロセスを解決するための答えは、ツリーDFSの過程で見つけるために誰かを見つけ、答えを解決するためのプロセスを分析します木のDFS、我々はMNを使用することができます[RT]、MX [RT]ルートサブツリーを記録するために、配列をRTにはZhekeプレフィックスとプレフィックスと最小値が含まれています、
そして、プロセスのDFSは、常にサブツリーで更新することができ、その後、我々はO(1)すべての単一のサブツリーに答えを計算し、全体的な複雑さはO(n)とのです
デカルトの木:
単調なスタックによって構成され、このプロセスは、それが右の子ツリー風雲デカルト素子P対応ノードが、オリジナルで、彼の素子Pよりも小さくを見つける前に、O(N)、スタック上のxの各要素でありますデカルトツリーのリーフノードが挿入されるように、Q右息子がない要素場合、現在の挿入要素xとなり、前者右Qの息子はスタックの最後の要素であるスタックを息子を残し、すなわち、挿入位置であります右スタックの先頭の要素の子ではありません
特性のデカルト木:バイナリ検索ツリーを満たす要素インデックスの特性は、要素の値を満たす特性がスタック
デカルトルートノードは、スタックの単調底スタック要素だけでなく、全体のシーケンスの最小値であり、すべての単一のルートのサブツリーは、最小の範囲内である、LCAのツリーの2つの要素は、問題を解決するために使用されてもよいRMQ
#include <ビット/ STDC ++ H.> 使用して 名前空間STD; 使用 = LL ロング ロング; のconst int型 N = 3E6 + 5。 、 INT A [N]; LL B [N]; int型息子[N] [ 2 ]、N-; / / 0 1左右の息子の息子の int型STA [N]; LLマンガン[N]、MX [N]; //は、現在のサブツリー最小と最大プレフィックス記録 LL ANS = - 3E18を、 無効 DFS(int型 RT、int型 L、INT R&LT) { IF(SON [RT] [ 0 ])DFS(SON [RT] [ 0 ]、L、RT- 。1); IF(息子[RT] [ 1。)DFS(息子[RT] [] 1。 ]、+ RT 1。、R&LT); // 左部分木のL-1この点を含んでいないが、しかし、我々は考慮に入れ、この接頭辞をしたいとそうでない場合は、ほとんどが[L]をbに計算され、ルートノード、B [RT]を含まない右サブツリーを考慮すべきである LL minL =分(MN [息子[RT] [ 0 ]、B [L- 1 ]) ; LLのMaxL = MAX(MX [ソン[RT] [ 0 ]、B [L- 1 ]); LL MINR =分(MN [ソン[RT] [ 1 ]、B [RT]); LL MAXR = MAX(MX [ソン[RT] [ 1 ]、B [RT]); ANS = MAX(ANS、A [RT] *(maxr- minL)); ANS = MAX(ANS、A [RT] *(MINR - MaxLの)); //書き込み電流も考慮されるサブルート のMn [RT] = 分(minL、MINR); MX [RT] = MAX(MaxLの、MAXR); } int型のmain() { int型N-、 IOSの:: sync_with_stdio(falseに); cin.tie(0 ); cout.tie(0 ); CINを >> N-; int型のトップ= 0 ; のための(INT I = 1 ; I <= N; I ++は) { CIN >> A [I]。 一方、(トップ&& A [I] <[STA [トップ])ソン[I] [ 0 ] STAを= [top--]; もし(トップ)息子[STA [トップ] [ 1 ] = I。 STA [ ++トップ] = I; } のために(int型 i = 1 ; iがn = <; iは++ ) { CIN >> B [i]は、 B [I] + = B [I- 1 ]。 } MN [ 0 ] = 3E18; MX [ 0 ] = - 3E18。 DFS(STA [ 1 ]、1 、N) coutの << ANS << てendl; リターン 0 ; }