poj2482 Stars in Your Window(成段更新+扫描线)
来源:互联网 发布:淘宝货源外国 编辑:程序博客网 时间:2024/04/30 13:23
http://poj.org/problem?id=2482
题意:给你n个星星的x,y,val,求用一个长w宽h圈住的最大亮度的值(还有这题前缀长的不忍直视啊)。
思路:这题关键点在于对问题的转化,按照最笨的暴力枚举只会超时。这里我们设刚开始给的框代号X,以ABC点为中心临时做出来的框为代号ABC...。我们知道一个矩形的中心点可以代表它的位置,那么以A为中心,作w、h的矩形A,此矩形的范围表示框X的中心点在这个范围内即可圈住该点。设想如果有两个矩形A和B有交集,那么交集部分表示既可以圈住A点,也可以圈住B点,所以任意矩形的交集表示可以圈住任意的点。那么这里求框内最大亮度就转化成了求覆盖面积的最大值。
这样的话就是成段更新求最值+扫描线的思路了。那么点如何代表矩形呢?按我们上面的思路是按照点为中心做矩形,这里直接将横坐标平移w个单位,所有点都平移效果不会变。离散纵坐标值,扫描线从左往右扫描。还要注意这里做出的矩形是有权值的,一条线段映射到线段树里就是成段更新,lazy也可以用上。
#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;typedef long long LL;const int N = 100010;const int INF = 1e8;struct line{ __int64 l, r; __int64 sum; __int64 add;}tree[8*N];struct node{ __int64 w, h; __int64 val; bool operator < (const struct node & tmp) const { if(w == tmp.w) return val < tmp.val; return w < tmp.w; }}point[8*N];__int64 y[N*8];void build(__int64 i, __int64 l, __int64 r){ tree[i].l = l; tree[i].r = r; tree[i].add = 0; tree[i].sum = 0; if(l == r) { return; } __int64 mid = (l+r) >> 1; build(i*2, l, mid); build(i*2+1, mid+1, r);}__int64 binsearch(__int64 key, __int64 k){ __int64 high = k; __int64 low = 1; while(high >= low) { __int64 mid = (high+low) >> 1; if(y[mid] == key) { return mid; } else if(y[mid] < key) { low = mid+1; } else high = mid-1; } return -1;}void update(__int64 i, __int64 l, __int64 r, __int64 val){ if(tree[i].l == l && tree[i].r == r) { tree[i].add += val; tree[i].sum += val; return; } if(tree[i].add) { tree[i*2].add += tree[i].add; tree[i*2+1].add += tree[i].add; tree[i*2].sum += tree[i].add; tree[i*2+1].sum += tree[i].add; tree[i].add = 0; } __int64 mid = (tree[i].l+tree[i].r) >> 1; if(mid >= r) update(i*2, l, r, val); else if(mid < l) update(i*2+1, l, r, val); else { update(i*2, l, mid, val); update(i*2+1, mid+1, r, val); } tree[i].sum = max(tree[i*2].sum, tree[i*2+1].sum);}int main(){ // freopen("in.txt", "r", stdin); __int64 n, w, h; while(~scanf("%I64d%I64d%I64d", &n, &w, &h)) { for(__int64 i = 1; i <= n; i++) { scanf("%I64d%I64d%I64d", &point[i].w, &point[i].h, &point[i].val); y[i] = point[i].h; y[i+n] = point[i].h+h; point[i+n].w = point[i].w+w; point[i+n].h = point[i].h; point[i+n].val = -point[i].val; } sort(point+1, point+1+n*2); sort(y+1, y+1+n*2); __int64 k = 1; for(__int64 i = 2; i <= n*2; i++) { if(y[i-1] != y[i]) { y[++k] = y[i]; } } build(1, 1, k); __int64 ans = 0; for(__int64 i = 1; i <= n*2; i++) { __int64 l = binsearch(point[i].h, k); __int64 r = binsearch(point[i].h+h, k)-1; if(l > r) swap(l, r); // printf("%I64d %I64d\n", l, r); update(1, l, r, point[i].val); ans = max(ans, tree[1].sum); } printf("%I64d\n", ans); } return 0;}
0 0
- poj2482 Stars in Your Window(成段更新+扫描线)
- poj2482--Stars in Your Window(扫描线)
- 【poj2482】Stars in Your Window (扫描线+线段树)
- [POJ2482]Stars in Your Window(离散化+扫描线+线段树)
- POJ2482--Stars in Your Window
- poj2482 Stars in Your Window
- POJ2482-Stars in Your Window
- poj2482 Stars in Your Window hdu 5091 Beam Cannon 线段树 扫描线
- 扫描线 矩形内围起的星星亮度总和最大大 poj2482 Stars in Your Window
- poj2482 Stars in Your Window(线段树+扫描线+离散化)
- 线段树 poj2482 Stars in Your Window
- POJ2482 Stars in Your Window(线段树)
- POJ 2482 Stars in Your Window(扫描线)
- POJ 2482 Stars in Your Window(扫描线)
- 线段树经典题目:POJ2482 Stars in Your Window
- POJ_2482 Stars in Your Window 扫描线 + 线段树
- 扫描线 POJ 2482 Stars in Your Window
- poj 2482 Stars in Your Window(线段树+扫描线)
- leetcode 151 Reverse Words in a String
- Android 多版本Api适配
- 【bzoj4567】[Scoi2016]背单词 贪心+trie树
- 洛谷【P1692】——部落卫队
- tcp 的一些问题
- poj2482 Stars in Your Window(成段更新+扫描线)
- microstation level2 0507
- iOS 属性声明在@implementation里与extension里的区别
- stl中的tuple(tie)
- Simple IOC 容器实现-基于注解
- BZOJ 3514 Codechef MARCH14 GERALD07加强版
- Excel错误“不能将对象移到工作表外”解决方法
- Android API之android.widget.Filterable
- linux fedora23 相关操作