poj 2482 Stars in Your Window 线段树 扫描线
2016-03-16 11:07
561 查看
题目
题目链接:http://poj.org/problem?id=2482题目来源:某人的线段树合集。
简要题意:天空中有些星星,它们有亮度,你拿个框来框星星,求框里星星亮度之和最大多少。
题解
这个题好理解然后做的时候灵光一现,不过想到做法之后很久之后才去写了。线段树记录的是以某位置为起点的框里有多少亮度和。
将星星转化为对[x−w+1,x][x-w+1,x]内的位置增加/减少一个亮度,也就是区间更新。
求左边到哪里可以用尺取法直接线性做,二分也是可以的。
首先必然是要离散化的,我选择了对xx,然后y−h,yy-h,y来离散化。因为y+hy+h溢出,所以平移下。
以yy轴为基准建立扫描线,y−hy-h处加上一条线段,yy处去掉。
然后每轮去对线段树的根去求结果就行了。
代码
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int,int> PII; // head const int N = 1e5+5; struct Star { int x, y, b; }; struct Seg { int x1, x2, add; Seg(int x1, int x2, int add) : x1(x1), x2(x2), add(add) {} }; struct SegmentTree { #define lson (rt<<1) #define rson ((rt<<1)|1) #define MID ((L+R)>>1) #define lsonPara lson, L, MID #define rsonPara rson, MID+1, R const static int TN = N << 2; int t[TN]; int lazy[TN]; void pushUp(int rt) { t[rt] = max(t[lson], t[rson]); } void pushDown(int rt, int L, int R) { if (lazy[rt]) { lazy[lson] += lazy[rt]; lazy[rson] += lazy[rt]; t[lson] += lazy[rt]; t[rson] += lazy[rt]; lazy[rt] = 0; } } void build(int rt, int L, int R) { lazy[rt] = t[rt] = 0; if (L == R) return; build(lsonPara); build(rsonPara); pushUp(rt); } void modify(int rt, int L, int R, int l, int r, int v) { if (l > R || r < L) return; if (l <= L && r >= R) { lazy[rt] += v; t[rt] += v; } else { pushDown(rt, L, R); modify(lsonPara, l, r, v); modify(rsonPara, l, r, v); pushUp(rt); } } }; Star star ; int x , y[N*2], l ; vector<Seg> a[N*2]; SegmentTree st; int main() { int n, w, h; while (scanf("%d%d%d", &n, &w, &h) == 3) { for (int i = 0; i < n; i++) { scanf("%d%d%d", &star[i].x, &star[i].y, &star[i].b); x[i] = star[i].x; y[i] = star[i].y - h, y[n+i] = star[i].y; } sort(x, x + n); sort(y, y + 2 * n); int xn = unique(x, x + n) - x; int yn = unique(y, y + 2 * n) - y; int lb = 0; for (int i = 0; i < xn; i++) { while (x[i] - x[lb] >= w) lb++; l[i] = lb; } for (int i = 0; i < n; i++) { int x2 = lower_bound(x, x + xn, star[i].x) - x; int x1 = l[x2]; int y1 = lower_bound(y, y + yn, star[i].y - h) - y; int y2 = lower_bound(y, y + yn, star[i].y) - y; a[y1].push_back(Seg(x1, x2, star[i].b)); a[y2].push_back(Seg(x1, x2, -star[i].b)); } st.build(1, 0, xn); int ans = 0; for (int i = 0; i < yn; i++) { for (int j = 0; j < a[i].size(); j++) { Seg &cur = a[i][j]; st.modify(1, 0, xn, cur.x1, cur.x2, cur.add); } ans = max(ans, st.t[1]); a[i].clear(); } printf("%d\n", ans); } return 0; }
相关文章推荐
- java 最近将工作中用到的工具总结——日期工具
- 在写一个iOS应用之前必须做的7件事(附相关资源),优秀实践,供参考
- 移动端H5各种各样的列表的制作方法(六) by FungLeo
- java实现在线预览office文档
- 会话技术cookie
- java中线程分两种,守护线程和用户线程。
- memcached的安装与开启脚本
- roc与prc
- SQLite操作
- 重新配置android开发环境(由32位到64位)
- eclipse自动补全的设置
- 数据结构(8)线性表之静态链表
- 日志搜集、过滤及推送处理框架logstash及fluentd总结
- backbone的view代码
- Silverlight 错误解决方案
- Git总结
- oracle分区提高篇
- [Bundling and Minification ] 三、缩小
- java.lang.OutOfMemoryError异常解决方法
- TCP/IP入门(3)---运输层 据说是面试最主要的部分~~~