質問表面:http://codeforces.com/contest/1156/problem/E
Luogu翻訳:https://www.luogu.com.cn/problem/CF1156E
ドメイン名を変更するLuoguを言います。
効果:長さN pの順列、必要な間隔の数[L、R]満足し、P [L] + P [R] =最大{P [I]}、L <= I <= Rを考えます
これは、デカルトの木であることを述べました。
しかし、私はしません。
その後いじり。
第1の左の前処理[i]の位置の多数を、[i]をLと称します
R [i]は同様に右へ。
この要求は、単調スタックすることができます。
次に、LとRを列挙することができます。
しかし、明らかにそれが爆発します。
しかし、被験者に、あなたは片側のみを列挙することができます。
他の側へ直接アクセスすることはありません。
例えば、Lは、P [R] = PMAX-P [L]を列挙
唯一の右のそれには何のp [R]が存在しないことを知っています。
コードは以下の通りであります:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 MAXN = 2 * 1E5 + 10 。 int型のn、[MAXN]、POS [MAXN]。 長い 長いANS; INTをL [MAXN]、R [MAXN]は、[MAXN]です。 INT メイン() { scanf関数(" %のD "、&N) 以下のために(int型 i = 1 ; iが<= N; iが++ ){ scanf関数(" %dを"&[I])。 POS [I] = I。 } int型のトップ=0 ; 以下のために(int型 i = 1 ; iは= N <; iは++ ){ 一方(上部&& [S [トップ] <[I])をtop-- 。 L [I] =のS [トップ]。 S [ ++トップ] = I。 } トップ = 0 ; S [トップ] = N + 1 。 以下のために(int型 I = N; I; i-- ){ 一方(上部&& [S [トップ] <[i])とtop-- 。 R [I] =のS [トップ]。 S [ ++トップ] = I。 } のための(INT I = 1; iが<= N; iは++ ){ 場合(IL [I] <R [I] - I){ ため(INT J = L [I] + 1、J <I、J ++ ) 場合(POS [I] -a [J]]>私は、POSを[I] -a [J] <R [i])とANS ++ &&します。 } 他{ ための(int型 J = I + 1、J <R [I]; J ++ ) 場合(POS [[I] -a [J] <私は、POSを&& [[I] -a [J]]> L [i])と++ ANS 。 } } のprintf(" %d個の\ n " 、ANS)。 リターン 0 ; }