zoukankan      html  css  js  c++  java
  • BZOJ2850 巧克力王国

    题意:给定一堆点,每个点有权值,每次求在直线$Ax + By + C = 0$下的点的权值和

    KD树维护一下二维区间内的点权和就好恩。。。建树复杂度$O(n * logn)$,单次查询时间$O(sqrt{n})$

      1 /**************************************************************
      2     Problem: 2850
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:15568 ms
      7     Memory:4220 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 typedef long long ll;
     15 const int N = 5e4 + 5;
     16  
     17 inline int read();
     18  
     19 int n, m;
     20 int A, B, C, D;
     21  
     22 struct point {
     23     int x[2], v;
     24      
     25     point() {}
     26      
     27     inline void get() {
     28         x[0] = read(), x[1] = read(), v = read();
     29     }
     30      
     31     int& operator [] (int i) {
     32         return x[i];
     33     }
     34     inline bool operator < (const point &p) const {
     35         return x[D] < p.x[D];
     36     }
     37 } p[N];
     38  
     39 inline bool check(int x,int y) {
     40     return A * x + B * y < C;
     41 }
     42  
     43 struct KD_tree {
     44     KD_tree *ls, *rs;
     45     point p;
     46     int mn[2], mx[2];
     47     ll sum;
     48      
     49     KD_tree() {
     50         ls = rs = NULL;
     51         p = point();
     52         sum = 0;
     53     }
     54      
     55     #define Len (1 << 16)
     56     inline void* operator new(size_t) {
     57         static KD_tree *mempool, *c;
     58         if (mempool == c)
     59             mempool = (c = new KD_tree[Len]) + Len;
     60         *c = KD_tree();
     61         return c++;
     62     }
     63     #undef Len
     64      
     65     inline int calc() {
     66         return check(mn[0], mn[1]) + check(mn[0], mx[1]) + check(mx[0], mn[1]) + check(mx[0], mx[1]);
     67     }
     68      
     69     inline void update() {
     70         static int i;
     71         for (i = 0; i < 2; ++i) {
     72             mn[i] = mx[i] = p[i];
     73             if (ls) {
     74                 mn[i] = min(mn[i], ls -> mn[i]);
     75                 mx[i] = max(mx[i], ls -> mx[i]);
     76             }
     77             if (rs) {
     78                 mn[i] = min(mn[i], rs -> mn[i]);
     79                 mx[i] = max(mx[i], rs -> mx[i]);
     80             }
     81         }
     82         sum = p.v;
     83         if (ls) sum += ls -> sum;
     84         if (rs) sum += rs -> sum;
     85     }
     86       
     87     #define mid (l + r >> 1)
     88     void build(int l, int r, int now, point *P) {
     89         D = now;
     90         nth_element(P + l, P + mid, P + r + 1);
     91         p = P[mid];
     92         if (l < mid) {
     93             ls = new()KD_tree;
     94             ls -> build(l, mid - 1, !now, P);
     95         }
     96         if (mid < r) {
     97             rs = new()KD_tree;
     98             rs -> build(mid + 1, r, !now, P);
     99         }
    100         update();
    101     }
    102     #undef mid
    103      
    104     ll query() {
    105         ll res = 0;
    106         int cntl, cntr;
    107         if (check(p[0], p[1])) res += p.v;
    108         if (ls) {
    109             cntl = ls -> calc();
    110             if (cntl == 4) res += ls -> sum;
    111             else if (cntl) res += ls -> query();
    112         }
    113         if (rs) {
    114             cntr = rs -> calc();
    115             if (cntr == 4) res += rs -> sum;
    116             else if (cntr) res += rs -> query();
    117         }
    118         return res;
    119     }
    120 } *T;
    121  
    122 int main() {
    123     int i;
    124     n = read(), m = read();
    125     for (i = 1; i <= n; ++i)
    126         p[i].get();
    127     T = new()KD_tree;
    128     T -> build(1, n, 0, p);
    129     while (m--) {
    130         A = read(), B = read(), C = read();
    131         printf("%lld
    ", T -> query());
    132     }
    133     return 0;
    134 }
    135  
    136 inline int read() {
    137     static int x, sgn;
    138     static char ch;
    139     x = 0, sgn = 1, ch = getchar();
    140     while (ch < '0' || '9' < ch) {
    141         if (ch == '-') sgn = -1;
    142         ch = getchar();
    143     }
    144     while ('0' <= ch && ch <= '9') {
    145         x = x * 10 + ch - '0';
    146         ch = getchar();
    147     }
    148     return sgn * x;
    149 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    WPF 文本滚动效果 渐变效果
    Unity3D 学习——入门资料整理
    命名管道 问题:信号灯超时问题
    Nginx 遇到的问题
    Nginx的安装配置 例子
    03 Spring的父子容器
    02 浅析Spring的AOP(面向切面编程)
    03 JVM的垃圾回收机制
    02 Java类的加载机制
    01 深入理解JVM的内存区域
  • 原文地址:https://www.cnblogs.com/rausen/p/4474834.html
Copyright © 2011-2022 走看看