码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2850

时间:2015-05-05 23:38:53      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

 

比较基础的KD树。每个节点维护一个BOX,包含包含当当前子树的点的最小矩形,以及点权和,然后用“整个矩形都在直线的一侧”和“整个矩形都不在直线的一侧”剪枝。

 

技术分享
  1 /**************************************************************
  2     Problem: 2850
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:27240 ms
  7     Memory:3740 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12 #define N 50010
 13 #define oo 1000000001
 14 #define fprintf(...)
 15 using namespace std;
 16  
 17 typedef long long dnt;
 18  
 19 struct Point {
 20     int x, y, h;
 21     void read() { scanf( "%d%d%d", &x, &y, &h ); }
 22     Point(){}
 23     Point( int x, int y, int h ):x(x),y(y),h(h){}
 24     bool in( dnt a, dnt b, int c ) {
 25         return a*x+b*y<c;
 26     }
 27 };
 28 typedef bool (*Cmp)( const Point &a, const Point &b );
 29 struct Box {
 30     int xmin, xmax;
 31     int ymin, ymax;
 32     dnt sum;
 33     Box():xmin(oo),xmax(-oo),ymin(oo),ymax(-oo){}
 34     void add( Point &p ) {
 35         xmin = min( xmin, p.x );
 36         xmax = max( xmax, p.x );
 37         ymin = min( ymin, p.y );
 38         ymax = max( ymax, p.y );
 39         sum += p.h;
 40     }
 41     void add( Box &b ) {
 42         xmin = min( xmin, b.xmin );
 43         xmax = max( xmax, b.xmax );
 44         ymin = min( ymin, b.ymin );
 45         ymax = max( ymax, b.ymax );
 46         sum += b.sum;
 47     }
 48     bool in( dnt a, dnt b, int c ) {
 49         return (a*xmin+b*ymin<c)
 50             && (a*xmax+b*ymin<c)
 51             && (a*xmin+b*ymax<c)
 52             && (a*xmax+b*ymax<c);
 53     }
 54     bool out( dnt a, dnt b, int c ) {
 55         return (a*xmin+b*ymin>=c)
 56             && (a*xmax+b*ymin>=c)
 57             && (a*xmin+b*ymax>=c)
 58             && (a*xmax+b*ymax>=c);
 59     }
 60 };
 61 struct Node {
 62     Point p;
 63     Box box;
 64     Cmp cmp;
 65     Node *ls, *rs;
 66 }pool[N], *tail=pool, *root;
 67  
 68 int n, m;
 69 Point pts[N];
 70 Cmp cmp[2];
 71  
 72 bool cmpx( const Point &a, const Point &b ) {
 73     return a.x<b.x;
 74 }
 75 bool cmpy( const Point &a, const Point &b ) {
 76     return a.y<b.y;
 77 }
 78 Node *build( int lf, int rg, int c ) {
 79     if( lf>rg ) return 0;
 80     Node *nd = ++tail;
 81     int mid=(lf+rg)>>1;
 82     nth_element( pts+lf, pts+mid, pts+rg+1, cmp[c] );
 83     nd->cmp = cmp[c];
 84     nd->p = pts[mid];
 85     nd->ls = build( lf, mid-1, !c );
 86     nd->rs = build( mid+1, rg, !c );
 87     if( nd->ls ) nd->box.add( nd->ls->box );
 88     if( nd->rs ) nd->box.add( nd->rs->box );
 89     nd->box.add( pts[mid] );
 90     fprintf( stderr, "(%d,%d,%d) ", pts[mid].x, pts[mid].y, pts[mid].h );
 91     return nd;
 92 }
 93 dnt query( Node *nd, int a, int b, int c ) {
 94     if( nd->box.in(a,b,c) ) return nd->box.sum;
 95     if( nd->box.out(a,b,c) ) return 0;
 96     dnt rt = 0;
 97     if( nd->ls ) rt += query( nd->ls, a, b, c );
 98     if( nd->rs ) rt += query( nd->rs, a, b, c );
 99     if( nd->p.in(a,b,c) ) rt += nd->p.h;
100     return rt;
101 }
102 int main() {
103     scanf( "%d%d", &n, &m );
104     for( int i=1; i<=n; i++ )
105         pts[i].read();
106     cmp[0] = cmpx;
107     cmp[1] = cmpy;
108     root = build( 1, n, 0 );
109     fprintf( stderr, "\n" );
110     for( int i=1,a,b,c; i<=m; i++ ) {
111         scanf( "%d%d%d", &a, &b, &c );
112         printf( "%lld\n", query(root,a,b,c) );
113     }
114 }
View Code

 

bzoj 2850

标签:

原文地址:http://www.cnblogs.com/idy002/p/4480316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!