トピックへのリンク:https://ac.nowcoder.com/acm/contest/883/G
タイトル効果:YES \(\ N-)石スタック、各スタック有する\(a_iを\)A、各々が瓦礫石の数が全ての非ゼロヒープ杭、石の各除去、から選択されていてもよいですとき(0 \)\勝ちます。私は(合計が奇数の場合は石の小石間隔の数の除去瓦礫石の最小数の山から選択される)を受賞することを保証します([L、R] \)\どのように多くの間隔を尋ねました。
ソリューション:もちろん、それらの範囲のために、間隔の最大値の\(MXの\)は\(合計\)の半分の合計を超えていない場合は、勝利を保証することができます。各\を考慮することができる(a_iを\)\の間隔最大値として([L_iを、R_iを] \)、減算部は、回答の要件を満たすことができない、請求項間隔が、これは、\を(私は\)を含むことに注意しなければなりません。
各列挙\(Iは\)、\(Lの\)行の左端分離された第1の二つのそのような間隔\([lは、i]が\)だけ条件が満たされない場合、分離に、2つの最左\(R&LTの\) \([L、R]が\)を正確に満たさないように、各時間\(Lの\)は、現在の\に到達するために追加されている(私は\)に
時間の複雑さは、助けを求めて、O(過剰なエネルギー)である兄のORZの複雑さを分析
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #define N 300001 の#define LL長い長 LL T、N、[N]、L [N]、R [N]、S [N]、[N] F、ANS。 ボイドRUA(LL CUR、LLのL、LL R) { LLのL、R。 L = UPPER_BOUND(S + L- 1、S + CUR + 1、S [cur- 1 ] -a [CUR]) - Sであり; L ++ 。 R = CUR。 一方、(L <= CUR) { R =分(R、(LL)(LOWER_BOUND(S + R + 1、S + R + 1、2LL * [CUR] + S [1- 1 ]) - S- 1 )) ; ANS- = R-MAX(CUR、MAX(F [L] + 1、L))+ 1 。 F [L] = MAX([L]、R F)。 L ++ ; } } ボイドのinit() { scanf関数(" %のLLD "、&N) 用(LL i = 1 ; iが<= N; iが++ ) のscanf(" %のLLD "、&[i])と、S [I] = sの[I- 1 ] + [I]、[I] = F I ; L [ 1 ] = 1、R [N] = N。 用(LL I = 2 ; iが<= N; iが++ ) { LL _= I; 一方、(_> 1 && [I]> = _- 1 ]) _ = L [_- 1 ]。 L [I] = _。 } のための(LL I = N- 1、I> = 1 ; i-- ) { LL _ = I。 一方、(_ <N && [I]> [_ + 1 ]) _ = R [_ + 1 ]。 R [I] = _。 } ANS = N *(N- 1)/ 2 。 用(LL I = 1 ; iが<= N; iが++ ) RUA(I、L [i]は、R [I])。 printf(" %LLDする\ n " 、ANS)。 } int型のmain() { // freopenは( "test.in"、 "R"、STDIN)。 scanf関数(" %のLLD "、&T)。 一方、(T-- )のinit(); リターン 0 ; }