BZOJ4520 [Cqoi2016]K远点对
人生第一发k-d tree
又是序列最大值最小值不初始化
于是卡成(n^2)/4
1 /************************************************************** 2 Problem: 4520 3 User: CYZ 4 Language: C++ 5 Result: Accepted 6 Time:1052 ms 7 Memory:5424 kb 8 ****************************************************************/ 9 10 #include<cstdio> 11 #include<climits> 12 #include<algorithm> 13 #include<queue> 14 #include<functional> 15 using namespace std ; 16 17 template < class T1 , class T2 > 18 void min_equal ( T1 & a , const T2 & b ) { 19 if ( a > b ) a = b ; 20 } 21 22 template < class T1 , class T2 > 23 void max_equal ( T1 & a , const T2 & b ) { 24 if ( a < b ) a = b ; 25 } 26 27 template < class T > 28 T sqr ( const T & o ) { return o * o ; } 29 30 struct Point { 31 int d [ 2 ] ; 32 Point ( const int x = 0 , const int y = 0 ) { 33 d [ 0 ] = x ; 34 d [ 1 ] = y ; 35 } ; 36 int & operator [] ( const int o ) { return d [ o ] ; } 37 const int & operator [] ( const int o ) const { return d [ o ] ; } 38 } ; 39 40 struct Rectangle { 41 int d [ 2 ] [ 2 ] ; 42 Rectangle ( const Point * begin , const Point * end ) { 43 d [ 0 ] [ 0 ] = INT_MAX ; 44 d [ 0 ] [ 1 ] = INT_MAX ; 45 d [ 1 ] [ 0 ] = INT_MIN ; 46 d [ 1 ] [ 1 ] = INT_MIN ; 47 while ( begin != end ) { 48 min_equal ( d [ 0 ] [ 0 ] , ( * begin ) [ 0 ] ) ; 49 min_equal ( d [ 0 ] [ 1 ] , ( * begin ) [ 1 ] ) ; 50 max_equal ( d [ 1 ] [ 0 ] , ( * begin ) [ 0 ] ) ; 51 max_equal ( d [ 1 ] [ 1 ] , ( * begin ) [ 1 ] ) ; 52 begin ++ ; 53 } 54 } 55 } ; 56 57 double Variance ( const Point * begin, const Point * end , const int d ) { 58 double sum1 = 0 , sum2 = 0 ; 59 for ( const Point * i = begin ; i != end ; ++ i ) 60 sum1 += (*i)[d]; 61 const double Average = sum1 / ( end - begin ) ; 62 for ( const Point * i = begin ; i != end ; ++ i ) 63 sum2 += sqr( (*i)[d] - Average ) ; 64 return sum2 ; 65 } 66 67 struct IntArrayCmp { 68 const int d ; 69 IntArrayCmp ( const int d = 0 ) : d ( d ) {} ; 70 bool operator () ( const Point & a , const Point & b ) const { 71 return a [ d ] < b [ d ] ; 72 } 73 } ; 74 75 struct Node : public Point , public Rectangle { 76 Node * ch [ 2 ] ; 77 Node ( Point * const begin , Point * const end ) : Rectangle ( begin , end ) { 78 const int d = Variance ( begin , end , 0 ) > Variance ( begin , end , 1 ) ; 79 Point * const mid = ( begin + ( end - begin ) / 2 ) ; 80 nth_element ( begin , mid , end , IntArrayCmp ( d ) ) ; 81 * ( ( Point * ) this ) = * mid ; 82 ch [ 0 ] = begin != mid ? new Node ( begin , mid ) : 0 ; 83 ch [ 1 ] = mid + 1 != end ? new Node ( mid + 1 , end ) : 0 ; 84 } 85 } ; 86 87 long long Dis2 ( const Point & a , const Point & b ) { 88 return sqr ( ( long long ) a [ 0 ] - b [ 0 ] ) + sqr ( ( long long ) a [ 1 ] - b [ 1 ] ) ; 89 } 90 91 long long MaxDis2 ( const Rectangle & a , const Point & b ) { 92 return max ( sqr ( ( long long ) a . d [ 0 ] [ 0 ] - b [ 0 ] ) , sqr ( ( long long ) a . d [ 1 ] [ 0 ] - b [ 0 ] ) ) + 93 max ( sqr ( ( long long ) a . d [ 0 ] [ 1 ] - b [ 1 ] ) , sqr ( ( long long ) a . d [ 1 ] [ 1 ] - b [ 1 ] ) ) ; 94 } 95 96 const int MAXN = 100000 + 20 ; 97 int N ; 98 int K ; 99 Point P [ MAXN ] ; 100 Node * R ; 101 102 void Print_Dfs ( const Node * const o ) { 103 if ( o == 0 ) return ; 104 printf ( "(%d,%d)" ,( * o ) . Point :: d [ 0 ] , 105 ( * o ) . Point :: d [ 1 ] ) ; 106 putchar ( '{' ) ; 107 Print_Dfs ( o -> ch [ 0 ] ) ; 108 putchar ( ',' ) ; 109 Print_Dfs ( o -> ch [ 1 ] ) ; 110 putchar ( '}' ) ; 111 } 112 113 priority_queue < long long , vector < long long > , greater < long long > > q ; 114 Point Aim ; 115 116 void Dfs ( const Node * const o ) { 117 if ( MaxDis2 ( * o , Aim ) <= q . top () ) return ; 118 const long long D2 = Dis2 ( * o , Aim ) ; 119 if ( q . top () < D2 ) { 120 q . pop () ; 121 q . push ( D2 ) ; 122 } 123 if ( o -> ch [ 0 ] && o -> ch [ 1 ] ) { 124 const long long d0 = MaxDis2 ( * ( o -> ch [ 0 ] ) , Aim ) ; 125 const long long d1 = MaxDis2 ( * ( o -> ch [ 1 ] ) , Aim ) ; 126 const int d = d1 >= d0 ; 127 Dfs ( o -> ch [ d ] ) ; 128 Dfs ( o -> ch [ d ^ 1 ] ) ; 129 } else { 130 if ( o -> ch [ 0 ] ) Dfs ( o -> ch [ 0 ] ) ; 131 if ( o -> ch [ 1 ] ) Dfs ( o -> ch [ 1 ] ) ; 132 } 133 } 134 135 int main () { 136 scanf ( "%d%d" , & N , & K ) ; 137 for ( int i = 0 ; i < N ; ++ i ) { 138 int x , y ; 139 scanf ( "%d%d" , & x , & y ) ; 140 P [ i ] = Point ( x , y ) ; 141 } 142 R = new Node ( P , P + N ) ; 143 /* 144 Print_Dfs ( R ) ; 145 putchar ( '\n' ) ; 146 */ 147 K *= 2 ; 148 for ( int i = 0 ; i < K ; ++ i ) q . push ( 0 ) ; 149 for ( int i = 0 ; i < N ; ++ i ) { 150 Aim = P [ i ] ; 151 Dfs ( R ) ; 152 } 153 printf ( "%lld\n" , q . top () ) ; 154 return 0 ; 155 }