标签:blog ar io os sp for on div log
不容易,kd-tree。。终于过了,wa了好久,然后快两个月没管它,今天终于过了。
题目意思很简单,然后做法就是用kd-tree找最邻近的点和次邻近的点。
有几个坑点,就是点积和叉积会爆int,然后就是我的几何模板挫了,点在线段上,由于没有判断点是否会和线段的端点重合,我一直wa。下午重新看题的时候突然想到这个点,哎。。总算过了,好开心。。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define mnx 21100
#define eps 1e-8
#define mod 1000000007
struct point{
int x, y, id;
point( int x = 0, int y = 0 ) : x(x), y(y) {}
point operator + ( const point &b ) const {
return point( x + b.x, y + b.y );
}
point operator - ( const point &b ) const {
return point( x - b.x, y - b.y );
}
LL len(){
return (LL)x * x + (LL)y * y;
}
bool operator == ( const point &b ) const {
return x == b.x && y == b.y;
}
};
LL dot( point a, point b ){
return (LL)a.x * b.x + (LL)a.y * b.y;
}
LL cross( point a, point b ){
return (LL)a.x * b.y - (LL)a.y * b.x;
}
LL sqr( int x ){ return (LL)x * x; }
bool on_segment( point p, point a1, point a2 ){
if( p == a1 || p == a2 ) return true;
return cross( a1 - p, a2 - p ) == 0 && dot( a1 - p, a2 - p ) < 0;
}
int point_in_polygon( point p, point *poly, int n ){
int wn = 0;
poly[n] = poly[0];
for( int i = 0; i < n; ++i ){
if( on_segment( p, poly[i], poly[i+1] ) ) return 1;
LL k = cross( poly[i+1] - poly[i], p - poly[i] );
int d1 = poly[i].y - p.y, d2 = poly[i+1].y - p.y;
if( k > 0 && d1 <= 0 && d2 > 0 ) wn++;
if( k < 0 && d2 <= 0 && d1 > 0 ) wn--;
}
if( wn != 0 ) return 1;
return 0;
}
bool cmpX( point a, point b ){
return a.x<b.x || (a.x==b.x&&a.y<b.y) || (a.x==b.x&&a.y==b.y&&a.id<b.id);
}
bool cmpY( point a, point b ){
return a.y<b.y || (a.y==b.y&&a.x<b.x) || (a.y==b.y&&a.x==b.x&&a.id<b.id);
}
bool cmp( point a, point b, bool div ){
return div ? cmpY( a, b ) : cmpX( a, b );
}
struct node{
point val;
node *ls;
node *rs;
bool exist, div;
};
node *root;
point in[mnx], ans;
LL dis;
node *build( int l, int r, bool div ){
if( l >= r ) return NULL;
int m = ( l + r ) >> 1;
nth_element( in + l, in + m, in + r, div ? cmpY : cmpX );
node *now = new node();
now->val = in[m], now->exist = 1, now->div = div;
now->ls = build( l, m, div & 1 );
now->rs = build( m+1, r, div & 1 );
return now;
}
void search( node *a, point d ){
if( a == NULL ) return;
if( a->exist ){
LL dd = ( d-a->val).len();
if( dis>dd || (dis==dd && ans.id > a->val.id) )
ans = a->val, dis = dd;
}
if( cmp( d, a->val, a->div ) ){
search( a->ls, d );
if( a->div ? sqr( a->val.y - d.y ) <= dis : sqr( a->val.x - d.x ) <= dis )
search( a->rs, d );
}
else{
search( a->rs, d );
if( a->div ? sqr( a->val.y - d.y ) <= dis : sqr( a->val.x - d.x ) <= dis )
search( a->ls, d );
}
}
void erase( node *a, point tmp ){
if( a->val.id == tmp.id ){
a->exist = 0; return ;
}
if( cmp( tmp, a->val, a->div ) )
erase( a->ls, tmp );
else erase( a->rs, tmp );
}
void insert( node *a, point tmp ){
if( a->val.id == tmp.id ){
a->exist = 1; return ;
}
if( cmp( tmp, a->val, a->div ) )
insert( a->ls, tmp );
else insert( a->rs, tmp );
}
point p[mnx], pp[mnx];
int main(){
freopen( "tt.txt", "r", stdin );
int cas, kk = 1;
scanf( "%d", &cas );
while( cas-- ){
printf( "Case #%d:\n", kk++ );
int n;
scanf( "%d", &n );
for( int i = 1; i <= n; ++i ){
scanf( "%d%d", &p[i].x, &p[i].y );
p[i].id = i;
}
int R, B, Q;
scanf( "%d", &R );
for( int cnt = 1; cnt <= R; ++cnt ){
printf( "Region %d\n", cnt );
scanf( "%d", &B );
for( int i = 0; i < B; ++i )
scanf( "%d%d",&pp[i].x, &pp[i].y );
int all = 0;
for( int i = 1; i <= n; ++i ){
if( point_in_polygon( p[i], pp, B ) )
in[all++] = p[i];
}
root = build( 0, all, 0 );
scanf( "%d", &Q );
point q;
while( Q-- ){
scanf( "%d%d", &q.x, &q.y );
dis = 1000000000000000;
search( root, q );
point tmp = ans;
printf( "%d ", ans.id );
erase( root, tmp );
dis = 1000000000000000;
search( root, q );
printf( "%d\n", ans.id);
insert( root, tmp );
}
}
}
return 0;
}
标签:blog ar io os sp for on div log
原文地址:http://www.cnblogs.com/LJ-blog/p/4167272.html