https://www.luogu.com.cn/problem/P4168
タイトル
$ $ A n番目の桁、および二次問い合わせ$ M $、$ Q a_l、A_ {L + 1}、\ドット、モードA_R $何を
$ 1 \ leqslantのn \ leqslant 40000、1 \ leqslantメートル\ leqslant 50000、1 \ leqslant a_iを\ leqslant10 ^ 9 $
問題の解決策
初めてのブロック
この方法の一つ
統計nがない、非常に大きいので、後にそうすることができます離散データの数
だから、直接最大をカウントすることができます。そのような複雑さは確かに$ \ mathcal {O}(M \ n倍)$、タイムアウトであります
あなたは、このようなブロックに分割$ T $として、事前にいくつかのブロックテーブルを再生しようとした後、最大$ \ binom {T} {2}事前に$ブロックを置くと、それは保存されていることができます
クエリは$ 2 \回まで過ごすたびはそう\ lfloor N / T \ rfloor $時間、時間の複雑さは、$ $ \ mathcal {O}(T ^ 2N + 2MN / t)であります
$ M $と$ N- $同じオーダーのとみなし、Nに、得られた$ T ^ 2N + 2N ^ 2 / T $、同じ大きさのオーダーを確保するために、セット$ tは2N = 2N ^ 2 / T $を得ました^ $ T = \ SQRT [3] {N} $
((+ b)は$を証明$ maxを(A、B)= \シータアルゴリズムの概要)次第に大きく又は複雑後未満の両側が増加するので、全体の発現の複雑さの漸進的増加をもたらします
ACコード
書式#include <cstdioを> 書式#include <CStringの> 書式#include <アルゴリズム> 書式#include <cmath> 書式#include <キュー> 書式#include <ベクトル> 名前空間stdを使用。 以下のための#define REP(I、B)(登録INT I =(); I <(B)、I ++) 以下のための#define REPE(I、B)(; I <=(B)登録INT I =()は、i ++) 以下のための#defineペール(I、B)(登録INT I =(); I> =(B); i--) #ifdefのsahdsg #define DBG(...)のprintf(__ VA_ARGS__) #else #define DBG(...)無効(0) #endifの 長い長いLLのtypedef。 #define MAXN 40007 #define MAXM 50007 MAXD 35の#define INT [MAXN]、B [MAXN]、C [MAXN]。 INT D [MAXD] [MAXD] [MAXN]。 今INT [MAXN]。 コリントT、L、及び、 INT X = 0。 インラインボイドはなかった(int型のF){ 今[F] ++; もし(現在[NA] <今[F] ||(現在[NA] ==今[F] &&今[1 + NA]> F)){ 今の[Na + 1] = F。 今すぐ[F] = [NA]。 } } インラインINTゴー(int型Z、INT Y){ もしiが(Z + 1)/ L、J = Y / Lを=。 int型のL = I * L、R = J * L; {(I <J)場合 REP(K、0、+ 2) 今[K] = D [i]は[J] [K]。 REP(F、Z、L)でした(C [F])。 REP(F、R、y)はなかった(C [F])。 }他{ memsetの(今、0、はsizeof今)。 REP(F、Z、Y)でした(C [F])。 } リターンX = B [今[1 + NA]。 } INTメイン(){ 整数N、M。scanf関数( "%D%D"、&N、&M)。 REP(I、0、N){scanf関数( "%のD"、および[I])。B [I] = [I];} ソート(B、B + N)。(B、B + N)-b一意= NA。 REP(I、0、N){ C [I] = LOWER_BOUND(B、B +、NA [I]) - B。 } memsetの(D、0、はsizeof D)。 T = POW((二重)N、(二重)1/3)。 L = T?N / T:N。 REP(I、0、T)REPE(J、I、T){ REP(F、I * L、J * L){ int型K = C [F]; // DBG( "*%D \ n"、K)。 D [i]は[J] [K] ++; IF(D [i]は[J] [K]> D [i]は[J] ||(D [i]は[J] [K] == D [NA] [I] [J] [NA] && K <D [i]は[J] [1 + NA])){ D [i]は[J] [] = D [i]は[J] [K]。 D [i]は[J] [+ 1] = K。 } } } REP(I、0、m)の{ int型のL0、R0; scanf関数( "%D%D"、およびL0、&R0)。 INT、L =(L0 + X - 1)%N + 1。 INT R =(R0 + X - 1)%N + 1。 (L> R)スワップ(L、R)であれば、 (L-1、R)行きます。 printf( "%dの\ n" は、X)。 } 0を返します。 }