Luoguziti
まず、問題を理解する:我々は、n個のセクションに、このシーケンスを入れて、各期間の終わりに新しい要素を挿入する以上のものではありません。(私はそれがナ非常に単純だと思います)
この問題なし手書きバランスの取れたツリーは、2つだけのアレイ、2つの多重集合などの変数と、ヒープはありません......
STは、[]とedは[]の要素と開始各セクションの最後の要素を表す、の2つの配列を維持しましょう。
私たちは、2つのマルチセット<整数>を維持しましょう、完全な名前の男、すべての要素(既存の値)を表します。もう一つは、すべての違いを表し、デルタと呼ばれます。
そして、ほとんどの......
コードの場合:
#include <cstdioを> する#include < 設定 > の#include <cstdlib> の#include <CCTYPE> 使用して 名前空間STD。 const int型 MAXN = 5E5 + 1E2; const int型 INF = 0x3f3f3f3f 。 マルチセット < 整数 > デルタ、フル; int型ST [MAXN]編[MAXN]。 int型 SRT = infファイル。 INTのN、M。 インラインボイド update_srt(INT X) { 多重集合 < 整数 > ::それをイテレータ=full.lower_bound(X)。 int型 NW = *それを- X; - それは、 NW =分(NWであり、X - * に); SRT = 分(SRT、NW)。 full.insert(X)。 } インラインボイド REPLAC(int型の POS、INT X) { delta.insert(ABS(X - ED [POS]))。 もし(!POS = N) delta.erase(delta.find(ABS(ST [POS + 1 ] - ED [POS])))、 delta.insert(ABS(ST [POS + 1 ] - X)); 編[POS]= X。 } インラインINT GetIntで() { int型 RET = 0、=解決1 。 チャー CH = GETCHAR()。 一方、(!isdigit(CH)) { 場合(CH == ' - ' ) 修正 = - 1 。 CH = GETCHAR()。 } 一方(isdigit(CH)) RET = RET * 10 +(CH - ' 0 ' )、 CH =getchar関数(); リターンのRET *の修正。 } int型のmain() { 静的 チャー STR [ 1 << 5 ]。 N = GetIntで()、M = GetIntで()。 以下のために(int型 i = 1 ; iが++; iが<= N ) ST [I] = ED [I] = GetIntで()。 full.insert(INF)、 full.insert( - INF)。 用(int型 iは= 1 ; iがN <I ++は) delta.insert(ABS(ST [I + 1 ] - ED [I]))。 以下のために(int型 i = 1 ; iは++; iが= N < ) update_srt(ST [I])。 以下のために(int型 I = 1、POSを、X; I <= M; iが++ ) { scanf関数(" %sの" 、STR)。 もし(* STR == ' I ' ) { POS = GetIntで()、X = GetIntで()。 update_srt(X)。 REPLAC(POS、X)。 } そう であれば(STR [ 4 ] == ' S ') printf(" %Dを\ n " 、SRT)。 他 のprintf(" %d個の\ nを"、* delta.begin()); } 戻り 0 。 }