BZOJ1218(线段树+扫描线)
1.扫描线扫描x轴,线段树维护y轴。
2.坐标+1,线段树是从1开始维护。然后让边长--,这样就能包含边上的点了。
3.为了保证点在正方形内:在x轴上利用差分的思想,在x出Add(val),在x+r(已经-1了)处Add(-val);在y轴上利用线段树维护1~5001这个区间,在y~y+r上Add(val)。
题解博客大家都是口胡感觉难以讲清这个事情,这篇博客虽然没解释但代码逻辑不错,看懂的。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <ctime> 7 #include <cctype> 8 #include <climits> 9 #include <iostream> 10 #include <iomanip> 11 #include <algorithm> 12 #include <string> 13 #include <sstream> 14 #include <stack> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <vector> 19 #include <list> 20 #include <fstream> 21 #include <bitset> 22 #define init(a, b) memset(a, b, sizeof(a)) 23 #define rep(i, a, b) for (int i = a; i <= b; i++) 24 #define irep(i, a, b) for (int i = a; i >= b; i--) 25 #define ls(p) p << 1 26 #define rs(p) p << 1 | 1 27 using namespace std; 28 29 typedef double db; 30 typedef long long ll; 31 typedef unsigned long long ull; 32 typedef pair<int, int> P; 33 const int inf = 0x3f3f3f3f; 34 const ll INF = 1e18; 35 36 template <typename T> void read(T &x) { 37 x = 0; 38 int s = 1, c = getchar(); 39 for (; !isdigit(c); c = getchar()) 40 if (c == '-') s = -1; 41 for (; isdigit(c); c = getchar()) 42 x = x * 10 + c - 48; 43 x *= s; 44 } 45 46 template <typename T> void write(T x) { 47 if (x < 0) x = -x, putchar('-'); 48 if (x > 9) write(x / 10); 49 putchar(x % 10 + '0'); 50 } 51 52 template <typename T> void writeln(T x) { 53 write(x); 54 puts(""); 55 } 56 57 const int maxn = 1e4 + 5, M = 5001; 58 int n, r, cnt; 59 struct Seg { 60 int l, r, mx, tag; 61 }t[(M + 5) << 2]; 62 struct node { 63 int x, y1, y2, val; 64 }c[maxn << 1]; 65 66 void build(int l, int r, int p) { 67 t[p].l = l, t[p].r = r; 68 if (l == r) { 69 t[p].mx = t[p].tag = 0; 70 return; 71 } 72 int mid = (l + r) >> 1; 73 build(l, mid, ls(p)); 74 build(mid + 1, r, rs(p)); 75 } 76 77 void push_down(int p) { 78 if (t[p].tag) { 79 int tag = t[p].tag; 80 t[ls(p)].mx += tag; 81 t[rs(p)].mx += tag; 82 t[ls(p)].tag += tag; 83 t[rs(p)].tag += tag; 84 t[p].tag = 0; 85 } 86 } 87 88 void Add(int l, int r, int p, int k) { 89 if (l <= t[p].l && t[p].r <= r) { 90 t[p].tag += k; 91 t[p].mx += k; 92 return; 93 } 94 push_down(p); 95 int mid = (t[p].l + t[p].r) >> 1; 96 if (l <= mid) Add(l, r, ls(p), k); 97 if (mid < r) Add(l, r, rs(p), k); 98 t[p].mx = max(t[ls(p)].mx, t[rs(p)].mx); 99 } 100 101 int Query(int l, int r, int p) { 102 if (l <= t[p].l && t[p].r <= r) { 103 return t[p].mx; 104 } 105 push_down(p); 106 int ret = 0; 107 int mid = (t[p].l + t[p].r) >> 1; 108 if (l <= mid) ret = max(ret, Query(l, mid, ls(p))); 109 if (mid < r) ret = max(ret, Query(mid + 1, r, rs(p))); 110 return ret; 111 } 112 113 bool cmp(node a, node b) { 114 if (a.x != b.x) return a.x < b.x; 115 return a.val > b.val; 116 } 117 118 int solve() { 119 int ans = 0; 120 build(1, M, 1); 121 rep(i, 1, n) { 122 int x, y, z; 123 read(x), read(y), read(z); 124 c[++cnt] = {x + 1, y + 1, y + r, z}; 125 c[++cnt] = {x + r, y + 1, y + r, -z}; 126 } 127 sort(c + 1, c + 1 + cnt, cmp); 128 129 for (int i = 1, j, k; i <= cnt; i = j) { 130 int tmp = c[i].x; 131 for (j = i; j <= cnt && c[j].x == tmp; j++); 132 for (k = i; k < j && c[k].val > 0; k++) { 133 Add(c[k].y1, c[k].y2, 1, c[k].val); 134 } 135 ans = max(ans, Query(1, M, 1)); 136 for (; k < j; k++) { 137 Add(c[k].y1, c[k].y2, 1, c[k].val); 138 } 139 } 140 return ans; 141 } 142 143 int main() { 144 read(n), read(r); 145 writeln(solve()); 146 return 0; 147 }