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 }

 

posted @ 2016-04-24 17:54  Chris_2  阅读(501)  评论(0编辑  收藏  举报