poj2482 Stars in Your Window
此题可用线段树或静态二叉树来做。
考虑用线段树:
很容易想到先限定矩形横轴范围再考虑在此纵轴上矩形内物品总价值的最大值。
那么枚举矩形横轴的复杂度是O(n)的,考虑如何快速获取纵轴上的最大值。
我们不可能再次枚举纵轴,依次统计,这样做事多余的。
考虑窗口在纵轴上的滑动,每上升到一个新的高度,在加入新元素的同时只需将最底层的那些值弹出队列即可。
这样我们需要考虑队列上元素和的最大值。
我们从反面考虑每个元素对特定队列(矩形纵轴位置)的贡献。
枚举窗口的上面一条边,那么元素对窗口贡献正值当且仅当H(element) < H(window_top) - b。
否则对窗口贡献0。
注意到变化是连续的,考虑统计所有高度不超过枚举高度的物品总价值减去那些高度低于窗口下端的物品总价值。
这样我们可以对每个点辅助构造一个对应的虚拟点,位置恰在该点上方b处,权值为是原点的相反数。
于是队列和的最大值变成统计前缀最大值。
y轴上离散化用线段是维护即可,x轴控制进出队。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + ;
typedef __int64 LL;
struct Seg{
LL l, r;
LL sum, maxl;
}seg[maxn << ];
LL n, a, b;
LL k;
LL base, len;
struct Point{
LL x, y, z;
Point(LL x = , LL y = , LL z = ) : x(x), y(y), z(z) {}
}t[maxn << ]; bool cmp1(Point a, Point b){
return a.y < b.y;
} bool cmp2(Point a, Point b){
return a.x < b.x;
} void build(LL u, LL l, LL r){
seg[u].l = l, seg[u].r = r;
seg[u].maxl = seg[u].sum = ;
if(r - l < ) return;
LL mid = (l + r) >> ;
build(u << , l, mid);
build(u << | , mid, r);
} void push_up(LL u){
seg[u].sum = seg[u << ].sum + seg[u << | ].sum;
seg[u].maxl = max(seg[u << ].maxl, seg[u << ].sum + seg[u << | ].maxl);
} void add(LL u, LL l, LL r, LL L, LL R, LL from, LL d){
if(l == L && r == R){
seg[u].maxl += d * t[from].z;
seg[u].sum += d * t[from].z;
return;
}
LL mid = (l + r) >> ;
if(R <= mid) add(u << , l, mid, L, R, from, d);
else if(L >= mid) add(u << | , mid, r, L, R, from, d);
push_up(u);
} int main(){
//freopen("in.txt", "r", stdin);
while(~scanf("%I64d%I64d%I64d", &n, &a, &b)){
for(LL i = , x, y, z; i <= n; i++){
scanf("%I64d%I64d%I64d", &x, &y, &z);
t[i] = Point(x, y, z);
t[i + n] = Point(x, y + b, -z);
}
len = n << ;
sort(t + , t + len + , cmp1);
base = t[].y;
t[].y = ;
for(LL i = ; i <= len; i++){
if(t[i].y == base) t[i].y = t[i - ].y;
else{
base = t[i].y;
t[i].y = t[i - ].y + ;
}
}
LL high = t[len].y;
sort(t + , t + len + , cmp2);
base = ;
while(base <= len && t[base].x - t[].x < a) ++base;
build(, , high + );
for(LL i = ; i < base; i++) add(, , high + , t[i].y, t[i].y + , i, );
LL ans = seg[].maxl;
LL pre = ;
for(LL i = base; i < len + ; i++){
LL tp = pre;
while(tp < len + && t[i].x - t[tp].x >= a) ++tp;
for(LL j = pre; j < tp; j++) add(, , high + , t[j].y, t[j].y + , j, -);
LL tem = i;
while(i < len && t[i + ].x == t[i].x) ++i;
for(LL j = tem; j <= i; j++) add(, , high + , t[j].y, t[j].y + , j, );
ans = max(ans, seg[].maxl);
pre = tp;
}
printf("%I64d\n", ans);
}
return ;
}
poj2482 Stars in Your Window的更多相关文章
- POJ2482 Stars in Your Window(扫描线+区间最大+区间更新)
Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I stil ...
- POJ2482 Stars in Your Window 和 test20180919 区间最大值
Stars in Your Window Language:Default Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K T ...
- POJ2482 Stars in Your Window 题解
Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I stil ...
- Poj2482 Stars in Your Window(扫描线)
题面 Poj 题解 下面内容引用自"李煜东 <算法竞赛进阶指南>"(对原文略有缩减,侵删): 因为矩形的大小固定,所以矩形可以由它的任意一个顶点唯一确定.我们可以考虑把 ...
- 【POJ2482】Stars in Your Window
[POJ2482]Stars in Your Window 题面 vjudge 题解 第一眼还真没发现这题居然™是个扫描线 令点的坐标为\((x,y)\)权值为\(c\),则 若这个点能对结果有\(c ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- 【POJ2482】【线段树】Stars in Your Window
Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw ...
- 51nod 1208 && POJ 2482:Stars in Your Window
1208 Stars in Your Window 题目来源: Poj 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 取消关注 整点上有N颗星星,每颗 ...
- POJ 2482 Stars in Your Window 线段树扫描线
Stars in Your Window Description Fleeting time does not blur my memory of you. Can it really be 4 ...
随机推荐
- CentOS 7 内核更新后删除旧内核
0.当前 # uname -sr Linux -.el7.x86_64 1.搜索查询 # rpm -q kernel kernel--.el7.x86_64 kernel--.el7.x86_64 k ...
- web server与app server有什么不同
简单来说,web服务器提供页面给浏览器,而app服务器提供客户端可以调用的接口.具体而言,我们可以说: Web服务器处理HTTP请求,而app服务器基于多种不同的协议,处理应用程序的逻辑问题. 以下将 ...
- 3D语音天气球(源码分享)——在Unity中使用Android语音服务
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...
- 同时启动多个Tomcat
一,修改配置文件server.xml的端口 C:\apache-tomcat-5.5.23-1\conf\server.xml用记事本什么的打开修改3个地方 第一: <Server port ...
- Tostring(); 括号中的参数 格式化字符串
最近在逛 msdn 发现 查到 getTypeCode 方法 看到里边居然有 tostring("D")这样的写法 运行了一遍 感觉可以显示值 然后就 ...
- sql 中各种锁随记
一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系 ...
- [OrangePi] Installation on SD Card
Download any of the available images (xz archive) from Mega or GoogleDrive Download scriptbin_kernel ...
- 【ipython技巧】使用shell命令
在ipython终端时,可能临时需要使用shell命令进行简单处理: 可以在shell命令前面使用 !(感叹号) 比如在win7,ipython下想要使用sublime新建一个py,可以这样 !sub ...
- syscolumns表中所有字段的意思
--syscolumns表中所有字段的意思 name sysname --列名或过程参数的名称. id int --该列所属的表对象 ID,或与该参数关联的存储过程 ID. xtype tinyint ...
- SQl中drop与truncate的区别
在对SQL的表操作时,我们因不同的需求做出相应的操作. 我来对比一下truncate table '表明'与drop table '表格名'的区别,跟大家一起学习. drop table '表格名'- ...