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
  • 相关阅读:
    Thinking in Java Reading Note(9.接口)
    Thinking in java Reading Note(8.多态)
    Thinking in Java Reading Note(7.复用类)
    SQL必知必会
    Thinking in Java Reading Note(5.初始化与清理)
    Thinking in Java Reading Note(2.一切都是对象)
    鸟哥的Linux私房菜笔记(1.基础)
    Thinking in Java Reading Note(1.对象导论)
    CoreJava2 Reading Note(2:I/O)
    CoreJava2 Reading Note(1:Stream)
  • 原文地址:https://www.cnblogs.com/rausen/p/4474834.html
Copyright © 2011-2022 走看看