長さn、A1、A2、...、のシーケンスを考えます。
各1に対して<= iがAJ <= AI + pを、任意のjに対して満足する最小の非負整数pを見つけ、<= N - SQRT(ABS(IJ))
各点の$ P = MAX([J] -a [I] + \ SQRT {| ijを|} $、考えられるDP、$ F [I] = MAX([J] -a [I] + \ SQRT {| IJ |} $
議論を除去するための、より一般的な方法の絶対値が逆方向に、その上に再びそれを行う、私はケースを$ <例えば、我々は唯一の$ jに対処する、分類することができます
このルートでは、式がクラスの傾きを最適化することができていないようだ何整理、単調な意思決定を考えます
証明:
ライセンスが必要:2つの決定ポイント$ P1、P2 $と$ I1 <I2の$について、$ P2 $からの転送が$に転送$ P2 $から$ i1の$区別に$ P1は$から$ i1の$移動と比べた場合$ P1 $よりも才能のI2の$
したがって、それは$ [P1] -a [I1] + \のSQRT {P1-I1} <[P2] -a [I1] + \のSQRT {P2-I1} $知られ、確認は[P1] -aを$ I2] + \のSQRT {P1-I2} <[P2] -a [I2] + \のSQRT {P2-I2} $
ルートの2つだけの方程式を発見し、$ I1、I2の$のシンプルな、あなたは、ルートから開始$ I1に注意を払うことができるように存在しているルートと同等のp-I2の$、<I2 $を、それが$ pを-I1です>関数の引数が少し小さくなり、同じ値が小さくなる側面
するとそれは、大小関係の関数値の変更の前に、引数と同じ変動値の後ろに、減少の傾きの平方根関数である何スロープ/誘導体と同様、について考えることができます。$ iの<jの、\のSQRT {I - \デルタ} - \のSQRT {I}> \ SQRT {J- \デルタ} - \のSQRT {J} $、それは明らかに単調変化の関数値量の位相引数の変化の少量である一方、
分割統治アプローチは書いていません
ハーフスタックプロセス:
1.すべての権利ポイント少ない$以上のチームヘッドを除外する私は要素は、その後、ヘッド素子左ポイントは$セット$ I $
2.アップデート$ Fチームのヘッドと[i]は$
3.すべての尾は$ I $より良い意思決定ではない除外するには
4.キューが空の場合は、直接に$ I $、そうでない場合:
$ posの$が尾を$ POS-1 $の右の点の要素を変更、尾の左端と一致する、または尾をポップしない場合は、ターニングポイント$ posの$を二分検索します
$ posの場合は<= N $ $ I $が挿入されました
#include <iostreamの> する#include <cstdioを> する#include <CStringの> する#include <cmath> 使用して 名前空間STD。 const int型 MAXN = 500009 ; int型のn、[MAXN]。 ダブルF [MAXN]、G [MAXN]、SQ [MAXN]。 構造体ノード{ int型のP、L、R。 } Q [MAXN]。 二重 CALC(int型 J、int型i)が{ 戻り [j]を+ SQ [I- J]。 } INTバウンド(INT T、INT I){ int型の POS = Q [t]は.R + 1、L = Q [t]は.L、R = Q [T] .R。 一方、(L <= R){ int型ミッド= L + R >> 1 。 もし(計算値(Q [t]は.P、MID)<計算値(I、MID))POS =中間、R =半ば1 。 他リットル=ミッド+ 1 ; } 戻りPOS。 } ボイドワーク(){ int型のヘッド= 1、尾= 0 、POS。 以下のために(int型 i = 1 ; iは= N <; iは++ ){ 一方(ヘッド<=尾&& Q [ヘッド] .R <I)ヘッド++; Q [ヘッド] .L = I。 F [I] = MAX([I]、計算値(Q [ヘッド] .P F、I) -[I])。 一方、(ヘッド<=尾&& CALC(Q [尾] .P、Q [尾] .L)<計算値(I、Q [尾] .L))tail-- 。 もし(ヘッド>尾部)Q [++尾] = (ノード){I、I、N}。 他に{ int型の POS = バインド(尾、I); もし(POS = Q [尾] .L!)Q [尾] .R = POS- 1 。 他 tail-- ; もし(POS <= N)Q [++尾] = (ノード){I、POS、N}。 } } } int型のmain(){ scanf関数(" %のD "、&N) 以下のための(int型私は=1 ; iが<= N; iが++)のscanf(" %dの"、&[i])と、SQ [I] = SQRT(i)を、 作業(); 以下のために(int型 I = 1、J = N; iはJ <; iは++、j-- ) スワップ([I]、[J])、スワップ(F [I]、F [J])。 作業(); 以下のために(int型 I = N; I> = 1 ; i-- ) のprintf(" %Dを\ n "、(INT )(CEIL(F [I])))。 }