羅区4357&BZOJ4520:[CQOI2016]遠点のK - 問題への解決策

https://www.lydsy.com/JudgeOnline/problem.php?id=4520

https://www.luogu.com.cn/problem/P4357

N面内の既知の座標を有する点が、はるかにユークリッド距離のK番目の点を見つけます。

KDTREEボードの問題?

(各ポイントの後に我々の操作は確かに二回カウントされますので、これまでのところ、我々は最終的には最初の値を取得するような答え2Kである、)2kのメンテナンス最も遠い値の前にヒープを開きます

以下のように歩き回るKDTREE上の各点を取る......

それを見るために、コードの残りの部分は......(実際には、PPTのいずれかからコピーしたコードのボードは非常に見覚えことを恐れていません)

書式#include <cmath> 
の#include <キュー> 
の#include <cstdioを> 
する#include <CStringの> 
の#include <iostreamの> 
の#include <アルゴリズム>
 使用して 名前空間をSTD。
typedefの長い 長いLL。
CONST  INT K = 2 CONST  INT N = 1E5 + 5 constの LL INF = 1E18;
インラインintはREAD(){
     int型 X = 0 W、= 0 ; CHAR CH = 0 一方、(isdigit(CH)!){W | = CH == ' - ' ; CH = GETCHAR();}
     ながら(isdigit(CH))X =(X << 3)+(X << 1)+( CH ^ 48)、CH = GETCHAR()。
    リターン?W - X:X;
}
INT D、N、K、ルート。
構造体ポイント{
     int型のD [K]。
    ブール 演算子(< CONSTポイント&)のconst {
         戻り D [D] < AD [D]。
    }
} [N]。
構造体KDTREE {
     int型の D [K]、S [ 2 ]、X [ 2 ]、Y [ 2 ]。
} P [N]。
PRIORITY_QUEUE <LL、ベクトル<LL>、大きな<LL>> Q。
#define LS TR [O] .S [0]
 の#define RS TR [O] .S [1]
 の#defineのC max(a、b)は、(<B = B:A)
 の#define CMIN(B )(> B = B:?)
 ボイド UPD(int型の F、int型X){
    (.X [F] TR CMIN 0 ]、T R [X] .X [ 0 ])のC max(T R [F] .X [ 1 ]、T R [X] .X [ 1 ])。
    CMIN(TR .AND [F] [ 0 ]、T R [X] .AND [ 0 ])のCmax(TR .AND [F] [ 1 ] TR [X] .AND [ 1 ])。
}
INTのビルド(int型 L、INT R、int型のD){
    D = D。INT =(L + R)O >> 1 
    nth_element( + 1、+ 0、A + R + 1 )。
    P [O] .D [ 0 ] = P [O] .X [ 0 ] = P [O] .X [ 1 ] = [O] .D [ 0 ]。
    TR [O] .D [ 1 ] = TR [O]・Y [ 0 ] = TR [O]・Y [ 1 ] = [O] .D [ 1 ]。
    もし(L <O)LS =ビルド(L、O- 1、D ^ 1 )、UPD(O、LS)。
    もし(O <R)RS =ビルド(O + 1、R、D ^ 1 )、UPD(O、RS)。
    返すoを。
}
ボイド挿入(){
     ++ N。INT X =読み取る()、Y = 読み取り();
    TR [n]は.D [ 0 ] = P [N] .X [ 0 ] = P [N] .X [ 1 ] = X。
    TR [n]は.D [ 1 ] = P [N]・Y [ 0 ] = P [N]・Y [ 1 ] = Y。
    int型 P =ルート、D = 0 ; P; D ^ = 1 ){
        UPD(P、N)。
        INT&NXT = TR [P] .S [TR [n]は.D [D]> = TR [P] .D [D]。
        もし(NXT == 0){NXT = N。リターン;}
         のp = NXT。
    }
}
インラインLL SQR(LL X){ リターン X * X;}
インラインLL H(INT O、点P){
     戻り MAX(SQR(PD [ 0 ] -TR [O] .X [ 0 ])、SQR(PD [ 0 ] -TR [O] .X [ 1 ]))
             + MAX(SQR(PD [ 1 ] -TR [O]・Y [ 0 ])、SQR(PD [ 1 ] -TR [O]・Y [ 1 ]))。
}
のクエリ(int型O、点p){
    LL TMP = SQR(TR [O] .D [ 0 ] -pd [ 0 ])+ SQR(TR [O] .D [ 1 ] -pd [ 1 ])、D [ 2 ]。
    もし(LS)D [ 0 ] = H(LS、P)。 D [ 0 ] = - INF。
    もし(RS)D [ 1 ] = H(RS、P)。 D [ 1 ] = - INF。
    もし(q.top()< TMP){q.pop(); q.push(TMP);}
     int型の OP = D [ 0 ] <= D [ 1 ]。
    もし(q.top()<D [OP])クエリ(TR [O] .S [OP]、P); OP ^ = 1 ;
    もし(q.top()<クエリ)[ON] D(TR [O] .S、P)[ON]。
}
INT メイン(){
    N = read()は、K = ()を読み取ります。
    以下のためにINT iが= 1 ; I <= N; I ++ ){
        [I] .D [ 0 ] =読み取る()、[I] .D [ 1 ] = 読み取ります();
    }
    ルート =ビルド(1、nは、0 )。
    以下のためにINT iが= 1 ; I <= 2 * kは、I ++)q.push(0 )。
    以下のためにINT iが= 1 ; I <= N; I ++ )クエリ(根、[I])。
    printf(" %のLLD \ n " 、q.top())。
    リターン 0 ;
}

+++++++++++++++++++++++++++++++++++++++++++

 +著者:luyouqi233。+

 +私のブログへようこそ:http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

おすすめ

転載: www.cnblogs.com/luyouqi233/p/12284132.html