bzoj 2850
比较基础的KD树。每个节点维护一个BOX,包含包含当当前子树的点的最小矩形,以及点权和,然后用“整个矩形都在直线的一侧”和“整个矩形都不在直线的一侧”剪枝。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }