BoxerTC

Kd tree

Oct 25th, 2014
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.78 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define sc( x ) scanf( "%d" , &x )
  5. #define REP( i , n ) for( int i = 0 ; i < n ; ++i )
  6. #define clr( t , val ) memset( t , val , sizeof( t ) )
  7.  
  8. #define pb push_back
  9. #define all( v ) v.begin() , v.end()
  10. #define SZ( v ) ((int)(v).size())
  11.  
  12. #define mp make_pair
  13. #define fi first
  14. #define se second
  15.  
  16. #define N 4000000
  17.  
  18. #define sqr(A) ((A)*(A))
  19.  
  20. double eps = 1e-8;
  21. int cmp (double a , double b = 0 ){
  22.     return a + eps < b ? -1 : a - eps > b ? 1 : 0 ;
  23. }
  24.  
  25. struct point {
  26.     double x , y ;
  27.     point (double a , double b ) : x ( a ) , y ( b ){ }
  28.     point () {}
  29.     point operator + ( point p ){ return point ( x + p.x , y + p.y ) ; }
  30.     point operator - ( point p ){ return point ( x - p.x , y - p.y ) ; }
  31.     point operator * ( double t ){ return point ( x * t , y * t ) ; }
  32.     double operator * ( point p ){ return x * p.x + y * p.y ; }
  33.     double operator % ( point p ){ return x * p.y - y * p.x ; }
  34.     bool operator == ( point p ){ return cmp ( x , p.x ) == 0 && cmp ( y , p.y ) == 0 ; }
  35.     bool operator < ( point p ) const{
  36.         int t = cmp ( x , p . x ) ;
  37.         if ( t ) return t < 0 ;
  38.         return cmp ( y , p . y ) < 0 ;
  39.     }
  40.  
  41. } ;
  42.  
  43. point T[ N ];
  44. int le[ N ] ,ri[ N ];
  45.  
  46. bool compx( const point &A , const point &B ){
  47.     return A.x<B.x;
  48. }
  49. bool compy( const point &A , const point &B ){
  50.     return A.y < B.y;
  51. }
  52.  
  53. //intervalocerrado[from,to]
  54. inline int make( int from , int to , bool byx = true ){
  55.     if( from > to ) return -1;
  56.     if( from == to ){
  57.         le[ from ] = ri[ from ] = -1;
  58.         return from;
  59.     }
  60.     int mid=(from+to)/2;
  61.     nth_element( T + from , T + mid , T + to + 1 , byx ? compx : compy );
  62.     le[ mid ] = make( from , mid - 1 , !byx );
  63.     ri[ mid ] = make( mid + 1 , to , !byx );
  64.     return mid;
  65. }
  66.  
  67. point p;
  68. int dist;
  69.  
  70. //busco la distancia al nodo mas cercano de p.
  71. //dist tiene q ser puesta en inf antes de hacer la query.
  72. void query( int node , bool bxy ){
  73.     if( node == -1 ) return;
  74.     int distnode = sqr( T[ node ].x - p.x ) + sqr( T[ node ].y - p.y );
  75.     dist = min( dist , distnode );
  76.     if( bxy ){
  77.         int len = sqr( T[ node ].x - p.x );
  78.         if( compx( T[ node ] , p ) ){
  79.             query( ri[ node ] , !bxy );
  80.             if( len <= dist )
  81.                 query( le[ node ] , !bxy );
  82.         }else{
  83.             query( le[ node ] , !bxy );
  84.             if( len <= dist )
  85.                 query( ri[ node ] , !bxy );
  86.         }  
  87.     }else{
  88.         int len = sqr( T[ node ].y - p.y );
  89.         if( compy( T[ node ] , p ) ){
  90.         query( ri[ node ] , !bxy );
  91.         if( len <= dist )
  92.             query( le[ node ] , !bxy );
  93.         }else{
  94.             query( le[ node ] , !bxy );
  95.             if( len <= dist )
  96.                 query( ri[ node ] , !bxy );
  97.         }
  98.     }
  99. }
  100. /*
  101. 3
  102. 0 0
  103. 1 1
  104. 2 2
  105.  
  106. 0 2
  107. */
  108. int main(){
  109.     int n;
  110.     cin >> n;
  111.     REP( i , n ) cin >> T[ i ].x >> T[ i ].y;
  112.     make( 0 , n - 1 );
  113.     dist = 1<<30;
  114.     double x , y;
  115.     cin >> x >> y;
  116.     p = point( x , y );
  117.     query( 0 , 1 );
  118.     cout << dist << endl;
  119. }
Advertisement
Add Comment
Please, Sign In to add comment