您的位置:首页 > 其它

BZOJ4520 [Cqoi2016]K远点对

2016-04-24 17:54 323 查看
人生第一发k-d tree

又是序列最大值最小值不初始化

于是卡成(n^2)/4

/**************************************************************
Problem: 4520
User: CYZ
Language: C++
Result: Accepted
Time:1052 ms
Memory:5424 kb
****************************************************************/

#include<cstdio>
#include<climits>
#include<algorithm>
#include<queue>
#include<functional>
using namespace std ;

template < class T1 , class T2 >
void min_equal ( T1 & a , const T2 & b ) {
if ( a > b ) a = b ;
}

template < class T1 , class T2 >
void max_equal ( T1 & a , const T2 & b ) {
if ( a < b ) a = b ;
}

template < class T >
T sqr ( const T & o ) { return o * o ; }

struct Point {
int d [ 2 ] ;
Point ( const int x = 0 , const int y = 0 ) {
d [ 0 ] = x ;
d [ 1 ] = y ;
} ;
int & operator [] ( const int o ) { return d [ o ] ; }
const int & operator [] ( const int o ) const { return d [ o ] ; }
} ;

struct Rectangle {
int d [ 2 ] [ 2 ] ;
Rectangle ( const Point * begin , const Point * end ) {
d [ 0 ] [ 0 ] = INT_MAX ;
d [ 0 ] [ 1 ] = INT_MAX ;
d [ 1 ] [ 0 ] = INT_MIN ;
d [ 1 ] [ 1 ] = INT_MIN ;
while ( begin != end ) {
min_equal ( d [ 0 ] [ 0 ] , ( * begin ) [ 0 ] ) ;
min_equal ( d [ 0 ] [ 1 ] , ( * begin ) [ 1 ] ) ;
max_equal ( d [ 1 ] [ 0 ] , ( * begin ) [ 0 ] ) ;
max_equal ( d [ 1 ] [ 1 ] , ( * begin ) [ 1 ] ) ;
begin ++ ;
}
}
} ;

double Variance ( const Point * begin, const Point * end , const int d ) {
double sum1 = 0 , sum2 = 0 ;
for ( const Point * i = begin ; i != end ; ++ i )
sum1 += (*i)[d];
const double Average = sum1 / ( end - begin ) ;
for ( const Point * i = begin ; i != end ; ++ i )
sum2 += sqr( (*i)[d] - Average ) ;
return sum2 ;
}

struct IntArrayCmp {
const int d ;
IntArrayCmp ( const int d = 0 ) : d ( d ) {} ;
bool operator () ( const Point & a , const Point & b ) const {
return a [ d ] < b [ d ] ;
}
} ;

struct Node : public Point , public Rectangle {
Node * ch [ 2 ] ;
Node ( Point * const begin , Point * const end ) : Rectangle ( begin , end ) {
const int d = Variance ( begin , end , 0 ) > Variance ( begin , end , 1 ) ;
Point * const mid = ( begin + ( end - begin ) / 2 ) ;
nth_element ( begin , mid , end , IntArrayCmp ( d ) ) ;
* ( ( Point * ) this ) = * mid ;
ch [ 0 ] = begin != mid ? new Node ( begin , mid ) : 0 ;
ch [ 1 ] = mid + 1 != end ? new Node ( mid + 1 , end ) : 0 ;
}
} ;

long long Dis2 ( const Point & a , const Point & b ) {
return sqr ( ( long long ) a [ 0 ] - b [ 0 ] ) + sqr ( ( long long ) a [ 1 ] - b [ 1 ] ) ;
}

long long MaxDis2 ( const Rectangle & a , const Point & b ) {
return max ( sqr ( ( long long ) a . d [ 0 ] [ 0 ] - b [ 0 ] ) , sqr ( ( long long ) a . d [ 1 ] [ 0 ] - b [ 0 ] ) ) +
max ( sqr ( ( long long ) a . d [ 0 ] [ 1 ] - b [ 1 ] ) , sqr ( ( long long ) a . d [ 1 ] [ 1 ] - b [ 1 ] ) ) ;
}

const int MAXN = 100000 + 20 ;
int N ;
int K ;
Point P [ MAXN ] ;
Node * R ;

void Print_Dfs ( const Node * const o ) {
if ( o == 0 ) return ;
printf ( "(%d,%d)" ,( * o ) . Point :: d [ 0 ] ,
( * o ) . Point :: d [ 1 ] ) ;
putchar ( '{' ) ;
Print_Dfs ( o -> ch [ 0 ] ) ;
putchar ( ',' ) ;
Print_Dfs ( o -> ch [ 1 ] ) ;
putchar ( '}' ) ;
}

priority_queue < long long , vector < long long > , greater < long long > > q ;
Point Aim ;

void Dfs ( const Node * const o ) {
if ( MaxDis2 ( * o , Aim ) <= q . top () ) return ;
const long long D2 = Dis2 ( * o , Aim ) ;
if ( q . top () < D2 ) {
q . pop () ;
q . push ( D2 ) ;
}
if ( o -> ch [ 0 ] && o -> ch [ 1 ] ) {
const long long d0 = MaxDis2 ( * ( o -> ch [ 0 ] ) , Aim ) ;
const long long d1 = MaxDis2 ( * ( o -> ch [ 1 ] ) , Aim ) ;
const int d = d1 >= d0 ;
Dfs ( o -> ch [ d ] ) ;
Dfs ( o -> ch [ d ^ 1 ] ) ;
} else {
if ( o -> ch [ 0 ] ) Dfs ( o -> ch [ 0 ] ) ;
if ( o -> ch [ 1 ] ) Dfs ( o -> ch [ 1 ] ) ;
}
}

int main () {
scanf ( "%d%d" , & N , & K ) ;
for ( int i = 0 ; i < N ; ++ i ) {
int x , y ;
scanf ( "%d%d" , & x , & y ) ;
P [ i ] = Point ( x , y ) ;
}
R = new Node ( P , P + N ) ;
/*
Print_Dfs ( R ) ;
putchar ( '\n' ) ;
*/
K *= 2 ;
for ( int i = 0 ; i < K ; ++ i ) q . push ( 0 ) ;
for ( int i = 0 ; i < N ; ++ i ) {
Aim = P [ i ] ;
Dfs ( R ) ;
}
printf ( "%lld\n" , q . top () ) ;
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: