スキルI:離散重複排除機能
用(int型私は= 1 scanfの(; I <= N-Iが++)" %のD "、&A [I])を、B [I] = A [I]; (Bソート + 1、B + N-+ 1 ); INT UNIQUE = nnの(B + 1、B + N-+ 1)-B- 1。 ; // Xの数は、その後、ポインタはNN、最初の番号の位置にNN X + 1を停止し、それ以降の繰り返し要素であると仮定するため(INT I = 1 ; I <= N; I ++の) ID [I] = LOWER_BOUND(Bの+ 1、B + NN + 1、[I]) - B;新しい離散値の後//
スキルII:できる永続的なデータ構造
患部を変更し、新しいポイントを記録する新しい点へのポインタは、容易に検索することができます
ボイドアップデータ(int型 L、INT R、INT&NW、INTプリ、INT X) { NW = ++ CNT。 T [NW] [事前] =さt; tは[NW] .SUM ++ 。 もし(L == R)のリターン; INT半ば=(L + R)>> 1 。 もし(MID> = X)アップデータ(L、中、T [NW]を得た。LC、T [事前]を得た。LC、X)。 他のアップデータ(MID + 1 、R、T [NW] .RC、T [事前] .RC、X)。 }
スキルIII:船舶の範囲は[R] -a [L-1]に分解することができます
各ブランチNを持っているにもかかわらず
INTクエリ(INT L、INT R、INT LL、INT RR、INT KK) { 場合(L == R)戻りL。 INT S = T [T [RR]を得た。LC] .SUM - T [T [LL]を得た。LC] .SUM。 INT半ば=(L + R)>> 1 。 場合(S> = KK)戻りクエリ(L、中、T [LL]を得た。LC、T [RR]を得た。LC、KK)。 他 戻りクエリ(MID + 1、R、T [LL] .RC、T [RR] .RC、kk- S)。 }
最後に:会長ツリーテンプレート
// luogu P3834 の#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 使用して 名前空間はstdを、 INTのN、M。 const int型 N = 200003 ; INT [N]、B [N]、ID [N]。 構造体ノード { int型の和、LC、RC。 } T [N * 40 ]。 int型のCNT、RT [N]。 INTのビルド(int型 L、INT R) { int型 RT = ++ CNT。 T [RT] .SUM = 0 。 もしリットル(!=R) { int型ミッド=(L + R)>> 1 。 T [RT]を得た。LC = ビルド(L、MID)。 T [RT] .RC =ビルド(MID + 1 、R)。 } 戻りRT; } ボイドアップデータ(int型 L、INT R、INT&NW、INTプリ、INT X) { NW = ++ CNT。 T [NW] [事前] =さt; tは[NW] .SUM ++ 。 もし(L == R)のリターン; INT半ば=(L + R)>> 1 。 もし(中期> =X)アップデータ(L、中、T [NW]を得た。LC、T [事前]を得た。LC、X)。 他のアップデータ(MID + 1 、R、T [NW] .RC、T [事前] .RC、X)。 } INTクエリ(INT L、INT R、INT LL、INT RR、INT KK) { 場合(L == R)戻りL。 INT S = T [T [RR]を得た。LC] .SUM - T [T [LL]を得た。LC] .SUM。 INT半ば=(L + R)>> 1 。 場合(S> = KK)戻りクエリ(L、中、T [LL]を得た。LC、T [RR]を得た。LC、KK)。 他 戻りクエリ(MID + 1、R、T [LL] .RC、T [RR] .RC、kk- S)。 } INT メイン() { scanfの(" %のDの%のD "、およびN-、&M) のための(INT I = 1 ; I <= N; I ++)scanfの(" %Dを"、&A [I])、B [I ] = A [I]、 ソート(Bの + 1、B + N-+ 1 ); int型 NN = UNIQUE(Bの+ 1、B + N-+ 1)-B- 1。 ; // Xの数は、その後、ポインタがNNを停止することを前提と番号x + 1の第1の位置における // 離散重量に対する RTを[ 0 ] =(ビルド1 、NN)を、 ため(INT I =。1 ; I <= N; I ++ ) { ID [I] = LOWER_BOUND(Bの+ 1、B + NN + 1、A [I]) - B; アップデータ(1、NN、RT [I]、RT [I- 1 ] 、ID [I]); //は、離散的な数にアレイを取る } // 離散した後に新しい値 int型、X、Y Kを、 一方(M-- ) { scanfの(" %D%D%D "、&X&Y、およびK); のprintf(" %d個の\ N- "、[クエリ(B 1、NN、RT [X- 1 ]、RT [Y]、K)]); // シリアル番号B配列にディスクリート } 戻り 0 。 }