如果按一般的思路来想,去求窗户能框住的星星,就很难想出来。
如果换一个思路,找出每颗星星能被哪些窗户框住,这题就变得非常简单了。
不妨以每个窗户的中心代表每个窗户,那么每颗星星所对应的窗户的范围即以其为中心的、W*H的矩形。把这些矩形的左边和右边,分别加上和减去其价值。而统计这些边只需要开一个线段树统计即可,用每次加边后得到的最大值更新答案。
需要注意的是,计算这些边上两点的坐标时可能出现0.5的情况,为了避免,把原坐标*2即可。而且坐标过大,需要离散化。
一开始打的时候,竟然,错了样例。仔细看了之后才发现窗户的长度为框住的点数+1,TAT
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 #include <iostream> 7 #include <map> 8 9 using namespace std; 10 11 #define ls (rt<<1) 12 #define rs ((rt<<1)+1) 13 typedef long long LL; 14 const int maxn = 20005; 15 int n, m, W, H; 16 struct Node 17 { 18 LL x, y1, y2, v; 19 Node (LL x = 0, LL y1 = 0, LL y2 = 0, int v = 0): 20 x(x), y1(y1), y2(y2), v(v) {} 21 bool operator < (const Node &AI) const 22 { 23 if (x == AI.x) 24 return v < AI.v; 25 return x < AI.x; 26 } 27 }line[maxn*2]; 28 LL t[maxn]; 29 struct Tree 30 { 31 LL mv[maxn*4], delta[maxn*4]; 32 void Build(int rt, int l, int r) 33 { 34 delta[rt] = mv[rt] = 0; 35 if (l == r) 36 return ; 37 int mid = (l+r)>>1; 38 Build(ls, l, mid); 39 Build(rs, mid+1, r); 40 } 41 void PushUp(int rt) 42 { 43 mv[rt] = max(mv[ls], mv[rs]); 44 } 45 void PushDown(int rt) 46 { 47 mv[ls] += delta[rt], mv[rs] += delta[rt]; 48 delta[ls] += delta[rt], delta[rs] += delta[rt]; 49 delta[rt] = 0; 50 } 51 void Update(int rt, int l, int r, int L, int R, int k) 52 { 53 if (L <= l && r <= R) 54 { 55 mv[rt] += k; 56 delta[rt] += k; 57 return ; 58 } 59 if (delta[rt] != 0) 60 PushDown(rt); 61 int mid = (l+r)>>1; 62 if (L <= mid) 63 Update(ls, l, mid, L, R, k); 64 if (R > mid) 65 Update(rs, mid+1, r, L, R, k); 66 PushUp(rt); 67 } 68 }T; 69 map <LL, int> num_y; 70 71 int main() 72 { 73 while (~scanf("%d %d %d", &n, &W, &H)) 74 { 75 W ++, H ++; 76 m = 0; 77 int Tcnt = 0; 78 for (int i = 1; i <= n; ++i) 79 { 80 LL x, y, v; 81 scanf("%lld %lld %lld", &x, &y, &v); 82 line[++m] = Node(x*2-(W-1)+1, y*2-(H-1)+1, y*2+(H-1)-1, v); 83 line[++m] = Node(x*2+(W-1), y*2-(H-1)+1, y*2+(H-1)-1, -v); 84 t[++Tcnt] = y*2-(H-1)+1, t[++Tcnt] = y*2+(H-1)-1; 85 } 86 sort(t+1, t+Tcnt+1); 87 int las_cnt = Tcnt; 88 Tcnt = 0; 89 for (int i = 1; i <= las_cnt; ++i) 90 if (t[i] != t[i-1] || i == 1) 91 { 92 t[++Tcnt] = t[i]; 93 num_y[t[i]] = Tcnt; 94 } 95 sort(line+1, line+m+1); 96 T.Build(1, 1, Tcnt); 97 LL ans = 0; 98 for (int i = 1; i <= m; ++i) 99 { 100 T.Update(1, 1, Tcnt, num_y[line[i].y1], num_y[line[i].y2], line[i].v); 101 ans = max(ans, T.mv[1]); 102 } 103 printf("%lld ", ans); 104 } 105 return 0; 106 }