問題の意味:長さnの配列、Q MEXの和演算結果のいずれか2つの間隔所与。
解決法:直接話セグメントツリーのアプローチ:私たちは、(1,1)MEXに気づいMEX(1,2 )、MEX(1,3)... 結果MEX(1、i)は、我々は、その後、非減少であります1つのピップ範囲MEXに委ねと、ここに焦点を懇願するための時間、その後、最初のツリーラインと魅力のメンテナンス結果を考慮してください。私たちはゾーンからの移行1つの結果は、2つのノードと左を指している方法を検討インターバル結果?私たちは、[1]あなたがエンドポイントとしての第2の区間の結果を得ることができ、このポイントに影響を与える削除するには、実際、限り1区間の終了点に注意してください、そしてどのように我々はこの点の影響を削除するには、[1]それは?私たちは、[1]に影響します削除した後であることがわかった[1]このセクションには、間隔の位置を表示さ隣1の位置を!この時間間隔の結果MEX> [1]、その結果[1]を削除するようにした場合は、[1]になるであろう。我々は、上記とMEX(1,1)MEX(1、n)をもたらすことが非減少されます。その後、我々は>半分MEXセグメントツリーに[1]ポイントを来ることができる、あなたは間隔を変更することができます。これは、統計的な削除回答数が影響を修正しながら、一方で、最終的にはACとなり続けています。
この質問は、ツリーラインソリューションは、問題のクラスのためのより多くの古典的なアプローチである:2つの間隔の和である任意の照会の結果、およびフロントを除去することによって、私たちができることをより迅速に発見したので、次への迅速な移行の数の結果間隔の結果は、その後、我々は(無駄qwqで、この知識こんにゃくに呼ばれる)プレフィックスツリーラインとして、この実践を検討することができます。
詳細コードを参照してください。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 CONSTの INT N = 2E5 + 10 。 int型N、[N]、F [N]、NXT [N]。 BOOL VIS [N]。 マップ < int型、int型 > 融点; LL和[N << 2 ]、タグ[N << 2 ]。 ボイド押し上げ(INT RT){ 和[RT] =和[RT << 1 ] +和[RT << 1 | 1 ]。 } 無効プッシュダウン(int型 RT、INT L1、INT L2){ 場合(タグ[RT] == - 1)のリターン; 和[RT << 1 ] =(LL)タグ[RT]・L1。タグ[RT << 1 ] = タグ[RT]。 合計[RT << 1 | 1 ] =(LL)タグ[RT] * L2。タグ[RT << 1 | 1 ] = タグ[RT]。 タグ[RT] = - 1 。 } ボイドビルド(INT RT、INT L、INT R){ 場合(L == R){ 和[RT] = F [L]。タグ[RT] = -1 ; 返します。 } 和[RT] = 0。タグ[RT] = - 1 。 INT半ば= L + R >> 1 。 (RT構築 << 1 、L、ミッド)。 構築(RT << 1 | 1、ミッド+ 1 、R); 突き上げ(RT)。 } ボイド更新(INT RT、INT L、INT R、INT QL、INT QR、INT V){ 場合(QL <= L && R <= QR){ 和[RT]=(LL)V *(R-L + 1)。タグ[RT] = V。 返します。 } INT半ば= L + R >> 1 。 プッシュダウン(RT、中間 -l + 1、R- MID)。 もし(QL <= MID)更新(RT << 1 、L、中間、QL、QR、V)。 もし(QR>中旬)更新(RT << 1 | 1、ミッド+ 1 、R、QL、QR、V); 突き上げ(RT)。 } LLクエリ(INT RT、INT L、INT R、INT QL、INT QR){ 場合(QL <= L && R <= QR)リターン和[RT]。 INT半ば= L + R >> 1 。 プッシュダウン(RT、中間 -l + 1、R- MID)。 LL RET = 0 。 もし(QL <= MID)RET + =クエリ(RT << 1 、L、中間、QL、QR)。 もし(QR>中旬)RET + =クエリ(RT << 1 | 1、ミッド+ 1 、R、QL、QR)。 リターンRET; } int型のmain() { 一方(scanf関数(" %のD "、&N)&& N){ ため(int型 i = 1 ; iが<= N; iは++)scanf関数を(" %のD "、および[I])。 以下のために(int型 i = 0 ; iが<= N; iは++)VISを[I] = 0 ; 以下のために(int型 i = 1 ; iは= N <; iは++ ){ 場合([i]が<= N)VIS [I] = 1 。 F [I] = F [I- 1 ]。 一方、(VIS [F [I])F [I] ++ ; } mp.clear()。 以下のために(int型 I = N; I; i-- ){ 場合(mp.count([I]))NXT [I] =融点[I]]。他の NXT [I] = N +1 ; MP [I] = I。 } ビルド(1、1 、N) LL ANS = 0 。 以下のために(int型私= 1 ; iが<= N; iが++ ){ ANS + =クエリ(1、1 、N iは、N) int型、L = I、R = NXT [I] - 1、Tは= [I]を、 一方、(L < R){ int型ミッド= L + R >> 1 。 もし(クエリ(1、1、nは、MID、MID)> T)、R =ミッド。他リットル=ミッド+ 1 ; } 場合(クエリ(1、1、N、R、R)> t)を 更新(1、1、N、R、NXT [I] - 1 、[I])。 } のprintf(" %LLDする\ n " 、ANS)。 } 戻り 0 。 }