zoukankan      html  css  js  c++  java
  • bzoj 2850

    比较基础的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, "
    " );
    110     for( int i=1,a,b,c; i<=m; i++ ) {
    111         scanf( "%d%d%d", &a, &b, &c );
    112         printf( "%lld
    ", query(root,a,b,c) );
    113     }
    114 }
    View Code
  • 相关阅读:
    [C++] inline内联函数使用方法
    [C++] new和delete运算符使用方法
    [C++] namespace命名空间和using用法
    [C++] 引用类型&
    [C++] wchar_t关键字使用方法
    [C++] typeid关键字使用方法
    json_encode转化索引数组之后依然还是数组的问题
    微信网页授权 的流程
    验证码比较hash_equals 方法
    laravel 模型观察器
  • 原文地址:https://www.cnblogs.com/idy002/p/4480316.html
Copyright © 2011-2022 走看看