51nod 1208 窗上的星星 | 线段树 扫描线
2017-10-18 22:12
375 查看
51nod 1208 Stars In Your Window
题面
整点上有N颗星星,每颗星星有一个亮度。用一个平行于x轴和y轴,宽为W高为H的方框去套星星。套住的所有星星的亮度之和为S(包括边框上的星星),求S的最大值。
Input
第1行:共3个数N, W, H,中间用空格分割,N为星星的数量,W为方框的宽度,H为方框的高度。(2 <= N <= 50000, 1 <= W, H <= 10^9)
第2 - N + 1行:每行3个数,X, Y, L,中间用空格分隔,分别表示星星的横坐标X,纵坐标Y,以及星星的亮度L。(1 <= X, Y <= 10^9,1 <= L <= 10000)
Output
输出方框能够套住的最大亮度和S。
Input示例
6 3 3
1 1 2
2 2 3
3 3 4
4 4 3
5 5 2
6 6 1
Output示例
12
用一个矩形表示一颗星星,矩形宽W高H,左下角卡在原来星星的位置。当一个点被“星星矩形”覆盖时,这个点的权值就加上星星的亮度。这样,权值最大的位置就是矩形方块最佳放置位置的右上角。
仍然是离散化后用扫描线做。
#include <cstdio> #include <cstring> #include <algorithm> #include <cctype> using namespace std; typedef long long ll; #define space putchar(' ') #define enter putchar('\n') #define INF 0x3f3f3f3f template <class T> bool read(T &x){ char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; else if(c == EOF) return 0; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; return 0; } template <class T> void write(T x){ if(x < 0) x = -x, putchar('-'); if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 1000005; int n, ans, W, H, lstX , tmp , cntX; struct Query { int h, l, r, x; bool operator < (const Query &b) const{ return h < b.h; } } q ; void init(){ read(n), read(W), read(H); for(int i = 1, x, y, z; i <= n; i++){ read(x), read(y), read(z); q[2*i-1].l = q[2*i].l = lstX[2*i-1] = x; q[2*i-1].r = q[2*i].r = lstX[2*i] = x + W; q[2*i-1].h = y; q[2*i].h = y + H + 1; q[2*i-1].x = z; q[2*i].x = -z; } sort(lstX + 1, lstX + 2 * n + 1); for(int i = 1; i <= 2 * n; i++) tmp[i] = lstX[i]; for(int i = 1; i <= 2 * n; i++) if(i == 1 || tmp[i] != tmp[i - 1]) lstX[++cntX] = tmp[i]; } int getX(int x){ return lower_bound(lstX + 1, lstX + cntX + 1, x) - lstX; } int data[4*N], lazy[4*N]; void pushdown(int k){ data[k << 1] += lazy[k], data[k << 1 | 1] += lazy[k]; lazy[k << 1] += lazy[k], lazy[k << 1 | 1] += lazy[k]; lazy[k] = 0; } void change(int k, int l, int r, int ql, int qr, int x){ if(ql <= l && qr >= r) return (void) (data[k] += x, lazy[k] += x); pushdown(k); int mid = (l + r) >> 1; if(ql <= mid) change(k << 1, l, mid, ql, qr, x); if(qr > mid) change(k << 1 | 1, mid + 1, r, ql, qr, x); data[k] = max(data[k << 1], data[k << 1 | 1]); } int main(){ init(); sort(q + 1, q + 2 * n + 1); for(int i = 1; i <= 2 * n; i++){ if(i == 1 || q[i].h != q[i - 1].h) ans = max(ans, data[1]); change(1, 1, cntX, getX(q[i].l), getX(q[i].r), q[i].x); } write(ans), enter; return 0; }
相关文章推荐
- [51nod 1208] Stars in Your Window(线段树,扫描线)
- 【51nod】1494 选举拉票 扫描线+线段树
- 【51nod】1461 稳定桌 扫描线+线段树
- 51Nod 1672 扫描线 + 线段树/树状数组
- 51nod 1494 选举拉票【贪心】【扫描线】【线段树】
- 51nod 1206 Picture 矩形周长求并 | 线段树 扫描线
- 51Nod - 1559 线段树 + 扫描线
- 51Nod 1208 Stars in Your Window(扫描线)
- 51nod 1208 && POJ 2482:Stars in Your Window【普通线段树】
- 51nod 1461 稳定桌【扫描线】【线段树】
- HDU 1542 Atlantis 线段树 (扫描线 + 离散化)
- POJ 1389 Area of Simple Polygons 线段树 扫描线
- hdu 1542 线段树之扫描线之面积并
- 51NOD 1210 矩阵查询 【线段树/树状数组】
- ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)
- 51nod 1593 公园晨跑 | ST表(线段树?)思维题
- HDU 1542【线段树--矩形面积的并,扫描线+离散化】
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
- 【jzoj4898】【人生的价值】【扫描线】【线段树】
- poj 1151 hdu 1542 Atlantis 线段树扫描线,详细讲解,(*^__^*) 嘻嘻……