質問は、表面:
iの数の各位置について、長さnの配列、iは、として定義されている美しい値を有する:配列の最長期間を見つける[Lを、R]、満足L≤I≤R、および[L、 R]の中央値A I(我々は第2の比較には、キーワードの最初の値には2つの位置のシーケンス番号、キーワードインデックスのサイズを比較する。この場合には[L、R]が唯一の可能な長さであります奇数)、Rは- L + 1美しいiの値です。
次に、クエリーQが存在し、各質問[L、R]は美しいクエリ区間[L、R]値の最大値を表します。
[Enter]を
入力整数nの最初の行、入力nは整数の2行目I、入力整数Qの3行目、Q代表間隔、二つの整数Lの次Q線、R(1-≤r)が 、 を表し間隔のエンドポイントについて。
[出力]
お問い合わせは各区間については、出力の回答
[データ範囲]
データ満足の30%N、Q≤50
データ満たすN 2000 Q≤の70%を
すべてのデータのために、2000年のn-、1000000≤Q、≤満たすI ≤1000000
まず、我々は非常に単純なアプローチを考えますが、ポジティブではない解決策:N ^ nlogn +トップにヒープと各位置の最大値の多くを通じて定数;およびSTテーブルがうまく扱うnlogn。
この質問は、その後慎重に掘削され、各位置について、値が彼の1よりも大きくなる、または0になり、その後、和は0であり、点を含むように、最大インターバル期間間隔を見つけます。
例えば、N ^ nlogn + nlognアルゴリズムは、N ^ N + nlognなる最適化します。
コードはスタックのトップの下に与えられます。
#include <ビット/ STDC ++。H> #define INC(I、B)(iは= intを登録する;私は= Bを<; Iは++)のため 名前空間stdを使用。 テンプレート<クラスnTの> インライン無効読む(NT&X) { チャーC、一方(C = GETCHAR(),! isdigit(c)参照)。 X = C ^ 48;ながら(C = GETCHAR()、isdigit(c)参照)、X = X * 10 + C-48。 } const int型MXR = 1E6 + 1E5; [MXR] int型。 PRIORITY_QUEUE <ペア<int型、int型>> Q1、Q2; // q1は大きな根ヒープあり、Q2は小さなヒープルートであります int型の年[MXR]。 【MXR] F INT [25]。 int型のn; INT [MXR]事前; 空のビルド() { INC(I、1、N)F [i]が[0] =のANS [I]。 INC(J、1,20){ {(; iが(1 << j)を±1 <= N I ++はiは1 = INT)のために F [I] [J] = MAX(F [I] [J-1]、F [I +(1 <<(j-1))] [J-1])。 } } INC(J、0,19){ INC(I、(1 << J)、(1 <<(j + 1)) - 1){ (I> MXR)ブレークであれば、 [I] = jで事前。 } } } メインint型() { (n)を読み出します。 INC(I、1、n)を読み出す([I])。 INC(I、1、N){ 一方、(q1.size())q1.pop(); 一方、(q2.size())q2.pop(); INC(J、I、N){ IF(q1.size()&& [J]> q1.top()最初の)q2.push(make_pair(-a [J]、J)); 他q1.push(make_pair([J]、J)); ((J-I + 1)%2 == 0){もし 持続する; } {(q2.size()>(J-I + 1)/ 2)一方 q1.push(make_pair(-q2.top()まず、q2.top()は、第2)。。); q2.pop(); } 一方、(q2.size()<(J-I + 1)/ 2){ q2.push(make_pair(-q1.top()まず、q1.top()は、第2)。。); q1.pop(); } 年[q1.top()秒] = MAX(年[q1.top()第二。]、(J-I + 1))。 } } ビルド(); int型Q; (Q)を読み込みます。 INC(I 1、Q){ INT X、Y。(x)を読み出します。(y)を読み出します。 INT logg =プレ[Y-X + 1]。 INT ANSS = MAX([Y-(1 << logg)+1] [logg] F [X] [logg F)。 printf( "%d個の\ n"、ANSS)。 } } / * 8 16 19 7 8 9 11 20 16 8 3 8 1 4 2 3 1 1 5 5 1 2 2 8 7 8 * /