ポータルタイトル:[https://codeforces.com/gym/102059/problem/J](https://codeforces.com/gym/102059/problem/J)
問題の意味:ヒストグラムを考えるとは、長さnの配列は、各カラムの高さは、各ヒストグラムにおける矩形の記録領域は、アレイが大に昇順でソートされ、異なるサブアレイがある表しあなたのLとRには、出力A [L]はA [R]にしましょう。
思考:モノトーン半分+ +スタックプライオリティキューが
最初単調各列拡張範囲に周りを取得スタック、2つの点[L]は、各列の拡張範囲として知られている領域のサイズで保存されている計算することができるどのくらいサブ矩形領域Sの少ないように答えをチェックするために幾分異なるサブ以下回答に等しい長方形の面積を算出することにより、バイナリサーチ[L]は、面積値Sを見つけるために、正当なものであるので、同一の値とは異なりますLまたはサブ矩形のより多く;、この領域を記録し、その後、領域の大きさに加えて得られた前の小領域の長さの面積によって各サブ矩形のプライオリティキューに格納されているが、最初のチームから取り出し、検査領域数はR&LTに達するまでサブ矩形が存在し、存在する場合、計算された量の存在は、回答に含まれるかどうかを、
以下のサブ矩形の数に等しい値の領域を計算する方法は、次の式を有します:
// // 2019年7月29日ONマイルによって作成されます。 // // ジム102059j // 半分+ +単調なプライオリティキュースタック する#include <ビット/ STDC ++。H> #define PSプッシュ の#define PB一back の#define融点make_pair 使用して 名前空間はstdを、 const int型 MAXN = 300005 ; typedefの長い 長いLL。 構造体ノード{ LL ID、H、W。 ノード(){} ノード(-1,11,11-のB、LLのC):ID(A)、H(B)、W(C){} ブール 演算子 <(constのノード&A)のconst { 戻り時間* W>ああ* AW。 } }。 構造体ヒストグラム{ LLのN、L、R、sumlen、H [MAXN]、L [MAXN]、R [MAXN]、ST [MAXN]。 LL INIT(int型N){ この - > N = N。 sumlen = 0 ; 以下のために(int型 i = 1 ; iが<= N; iは++)scanf関数を(" %I64d "、&H [i])と、sumlen + = H [I]、L [I] = 1、R [I] = N。 scanf関数(" %I64d%I64d "、&L&R)。 int型のテール= 0 ; 以下のために(int型 i = 1 ; iが<= N + 1、iは++ ){ 一方(テール> = 1 && H [ST [尾]]> H [I]){ R [ST [尾] = I- 1 。 L [I] =のL [ST [尾]。 テール - ; } もし(尾部)L [I] = ST [尾] + 1 。 ST [ ++尾] = I; } } getnum LL(LLのX、LLのY){ X = MAX(1LL、Y-X + 1 )。 リターン(Y + X)%2 == 0?(Y + X)/ 2 *(Y-X + 1):(Y-X + 1)/ 2 *(Y + X)。 } LL getlen(LLのX、LLのY、LLのZ、LL LEN){ 戻り MAX(0LL、ZY-のみ+ 2)-max(0LL、ZX-のみ+ 1)-max(0LL、ヒドロキシのみ+ 1 )。 } LL {(LLのX)を解きます LL合計 = 0 ; 以下のために(int型 i = 1 ; iが<= N; iは++ ){ 場合(H [I]> x)を続けます。 LL LEN = R [I] -1- [I] + 1 。 和 + = getnum(X / H [i]は、LEN)-getnum(X / H [i]は、R [I] -i)-getnum(X / H [i]は、I- L [I])。 } 戻り値の合計。 } LL binary_search(LL LLのL、 &ANS){ LL、LR = 1、RR = sumlen。 一方、(LR < RR){ 長い 長い半ば=(LR + RR)>> 1 。 長い 長いヴァル= (MID)を解きます。 もし(ヴァル< L){ LR =ミッド+ 1 ; } 他{ RR = 半ば; } } ANS = LR; 返す(LR)を解きます。 } ボイドの仕事(){ LL ANS = 0 。 LL TMP = binary_search(L、ANS)。 一方、(L <= R && L <= TMP){ printf(" %I64d " 、ANS)。 L ++ ; } PRIORITY_QUEUE <ノード> Q; 以下のために(int型 I = 1 Q.ps(ノード(I、H [i]は、ANS / Hを[I] +; iが++; iが<= N)1 ))。 ノードNXT。 一方、(L <= R){ NXT = Q.top()。 Q.pop(); = 場合(nxt.id> = 300005 || nxt.id <= 0)ブレーク。 LL TLEN = getlen(nxt.id、L [nxt.id]、R [nxt.id]、nxt.w)。 もし(!TLEN)続けます。 一方、(TLEN> 0 && L <= R){ printf(" %I64d "、nxt.h * nxt.w)。 酸素 - ; L ++ ; } ++ nxt.w; Q.ps(NXT)。 } } }。 ヒストグラム交流。 int型のmain() { LLのn; scanf関数(" %I64d "、&N) ac.init(N) ac.work(); リターン 0 ; }