HDU 6521 K番目の最短距離(議長バイナリツリー+)

質問の意味:

あなたのアレイを与えるために、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 ]、11000000、[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]、11000000、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 

 * /

 

おすすめ

転載: www.cnblogs.com/wrjlinkkkkkk/p/11278800.html