题意:给定一堆点,每个点有权值,每次求在直线$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\n", 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 }
时间: 2024-10-25 13:47:16