質問の意味:
あなたのアレイを与えるために、q回の依頼、オンライン強制、Pのk番目の最大の要素の範囲内であなたのたびに[L、R]およびp距離を尋ねます
アイデア:
大統領ツリーセグメントツリー重量のエキス[L、R]、及びその後の中間Pからの距離の半分
kに等しいよりだけ大きくなるように重みの値のセグメントツリー[P-MID、P +中間]番号を尋ねます
コード:
書式#include <iostreamの> の#include <cstdioを> する#include <アルゴリズム> 書式#include <cmath> の#include <CStringの> の#include < 文字列 > の#include <スタック> の#include <キュー> の#include <両端キュー> の#include < 設定 > #include <ベクトル> の#include <地図> の#define FST最初 の#define SC第二 の#define PB一back の#define MEM(A、B)のmemset(A、B、はsizeof(A)) の#define LSON Lを、中間、ルート< < 1 の#define rson半ば+ 1、R、根<< 1 | 1 #define LCルート<< 1つ の#define RCルート<< 1 | 1 使用して名前空間はstdを、 typedefをダブルデシベル。 typedefの長いダブルLDB。 typedefの長い長いLL。 typedefの符号なしの長い長いULL。 typedefのペア < int型、int型 > PI; typedefの対 <-1,11,11-> PLL。CONST DB EPS = 1E- 6 。 const int型 MOD = 1E9 + 7 。 const int型 MAXN = 2E7 + 2E6 + 100 ; const int型 MAXM = 4E6 + 100 。 const int型 INF = 0x3f3f3f3f 。 CONST dBのPI = ACOS( - 1.0 )。 int型のLS [MAXN]、RS [MAXN]、DAT [MAXN]。 int型のTOT; INTのN、Q。 INT [MAXM]。 int型のルート[MAXM]。 int型のトン。 int型インサート(INT今、int型の L、int型の R、int型のx、int型のval){ int型の P = ++ TOT。 LS [P] =のLS [今]; RS [P] = [今] RS; DAT [P] =DAT [今]。 もし(L == R){ DAT [P] + = ヴァル。 リターンのp; } INT半ば=(L + R)>> 1 。 もし(x <= MID)LS [P] = (LS [今]、L、中、X、ヴァル)を挿入します。 他の RS [P] =インサート(RS [今]、ミッド+ 1 、R、X、ヴァル)。 DAT [P] = DAT [LS [P]] + DAT [RS [P]]。 リターンのp; } INT(ASK INT、LSTをint型今、int型の L、int型の R、int型の L、INT {R) //printf( "%D%D%D%D%D%D \ n"は、LST、今、L、R、L、R)。 INT半ば=(L + R)>> 1 。 int型 ANS = 0 ; もし(L <= 1 && R <= R)を返す DAT [今] - DAT [LST]。 もし(L <= MID)ANS + = 尋ねる(LS [LST]、LS [今]、L、中、L、R)。 もし(MID <R)ANS + =(RS [LST]、RS [今]、ミッド+尋ねる1 、R、L、R)を、 戻るANSを。 } INT K、P。 ブール CMP(INT A、INT B){ 戻り ABS(AP)<ABS(B- P)。 } int型のmain(){ scanf関数("%のD "& T); ながら(t-- ){ int型 lstans = 0 ; MEM(DAT、0 ); TOT = 0 ; scanf関数(" %d個の%のD "、&N、&Q); のため(int型 Iを= 1 ; iが++; iが<= N ){ scanf関数(" %のD "、および[I]); 根[I] =インサート(ルート[I- 1 ]、1、1000000、[i]は、1)。 } 一方、(q-- ){ int型のL、R。 scanf関数(" %D%D%D%D "、&L&R&P、およびK)。 L ^ = lstans。 R ^ = lstans。 P ^ = lstans。 K ^ = lstans。 int型ANS; int型の L = 0 ; INTの R = 1000000 。 一方、(L <= R){ int型ミッド=(L + R)>> 1 。 INT RES =(ルート[1-尋ねる1 ]、根[R]、1、1000000、MAX(1、P-MID)、分(1000000、P + 中間の)); もし(RES> = K){ ANS = ミッド。 R =半ば1 。 } 他 L =ミッド+ 1 。 } lstans =のANS。 printf(" %d個の\ n " 、ANS)。 } } 戻り 0; } / * 1 10 2 31 2 45 5 4 1 5 1 2 5 3 2 * /