这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)。。。但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用) 
  题意就是在平面上给你一些星星,一定是整数点,每颗星星有一个亮度,然后给你一个固定大小只能移动不能旋转的矩形框,问你任意移动矩形框最多可以将星星的最大的亮度装进框内,注意框边上的星星不计算

  以前做过有个类似的题,但是数据范围小又很水,因为可以枚举每个点作为四个角分别统计就过了。可是这样是错的,因为可能有情况是四个点分别限制矩形框的四边,这样的情况就不能处理。 
  很多二维题都是二维变一维,先枚举一维,接着用一些数据结构高效的维护另一维。 
  这个题所使用的方法其实也是排序一维,然后模拟矩形框来维护两条扫描线在这一维上移动,接着处理第二维在限制长度内的最大值。换句话就是用两个指针维护x轴,接着用添加点,删除点的方式维护y轴。但是在限制长度下求最大区间和不太好做,我们可以模拟树状数组的区间更新,在每个点的(y轴+限制长度)的位置添加一个负的亮度,这样我们就转化为了求最大区间和(没有了限制长度),直接套一个线段树区间合并。注意这儿数据范围很大需要离散化,但是要搞清楚我们只需要离散化后的每个y值对应的是树上的哪个位置(其实就是第几大),使用map就可以解决

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Max=;
map<ll,int> mp;//离散化成1到coun
struct node
{
ll bri;
ll xx1,yy1;
} poi[Max];
struct nide
{
ll lmax,rmax,mmax,sum;
void init(ll num)
{
sum=lmax=rmax=mmax=num;
}
} segtr[Max*<<]; //再多开一倍空间
bool cmp1(struct node p1,struct node p2)
{
return p1.xx1<p2.xx1;
}
ll nmax(ll a,ll b)
{
return a>b?a:b;
}
void Upnow(int now,int next)
{
segtr[now].sum=segtr[next].sum+segtr[next|].sum;
segtr[now].lmax=nmax(segtr[next].lmax,segtr[next].sum+segtr[next|].lmax);
segtr[now].rmax=nmax(segtr[next|].rmax,segtr[next|].sum+segtr[next].rmax);
segtr[now].mmax=nmax(nmax(segtr[next].mmax,segtr[next|].mmax),segtr[next].rmax+segtr[next|].lmax);
return;
}
void Create(int sta,int enn,int now)
{
if(sta==enn)
{
segtr[now].init(0ll);
return;
}
int mid=dir(sta+enn,);
int next=mul(now,);
Create(sta,mid,next);
Create(mid+,enn,next|);
Upnow(now,next);
return;
}
void Update(int sta,int enn,int now,int x,ll y)
{
if(sta==enn&&sta==x)
{
segtr[now].sum+=y;
segtr[now].lmax+=y;
segtr[now].rmax+=y;
segtr[now].mmax+=y;
return;
}
int mid=dir(sta+enn,);
int next=mul(now,);
if(mid>=x)
Update(sta,mid,next,x,y);
else
Update(mid+,enn,next|,x,y);
Upnow(now,next);
return;
}
int main()
{
ll n,w,h;
while(~scanf("%lld %lld %lld",&n,&w,&h))
{
for(int i=; i<n; i++)
scanf("%lld %lld %lld",&poi[i].xx1,&poi[i].yy1,&poi[i].bri);
mp.clear();
for(int i=; i<n; i++)//建树前离散化y轴
{
mp[poi[i].yy1]=;
mp[poi[i].yy1+h]=;
}
int coun=;
map<ll,int>::iterator it;
for(it=mp.begin(); it!=mp.end(); ++it)
it->second=coun++;
coun--;
Create(,coun,);
int j=;//双指针作为扫描线
ll manx=;
sort(poi,poi+n,cmp1);
for(int i=; i<n; i++) //关键:模拟树状数组的区间更新,后面对应位置加一个负的亮度,则就求最大区间和
{
Update(,coun,,mp[poi[i].yy1],poi[i].bri);//加点
Update(,coun,,mp[poi[i].yy1+h],-poi[i].bri);//枚举的点
while(i!=j&&poi[i].xx1-poi[j].xx1>=w)
{
Update(,coun,,mp[poi[j].yy1],-poi[j].bri);//删点
Update(,coun,,mp[poi[j].yy1+h],poi[j].bri);
j++;
}
manx=nmax(manx,segtr[].mmax);
}
printf("%lld\n",manx);
}
return ;
}

POJ 2482 Stars in Your Window (线段树区间合并+扫描线)的更多相关文章

  1. 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 ...

  2. POJ 2482 Stars in Your Window 线段树

    如果按一般的思路来想,去求窗户能框住的星星,就很难想出来. 如果换一个思路,找出每颗星星能被哪些窗户框住,这题就变得非常简单了. 不妨以每个窗户的中心代表每个窗户,那么每颗星星所对应的窗户的范围即以其 ...

  3. POJ 2482 Stars in Your Window(线段树+扫描线)

    题目链接 非常不容易的一道题,把每个点向右上构造一个矩形,将问题转化为重合矩形那个亮度最大,注意LL,注意排序. #include <cstdio> #include <cstrin ...

  4. POJ 3368:Frequent values(线段树区间合并)

    题目大意,给出一段非降序列,求一些区间中出现频率最高的数的出现次数. 分析: 显然,区间中一个数多次出现必然是连续的,也就是最长的连续相等的一段. 用线段树解决,维护三个信息:一个区间最长连续的区间的 ...

  5. POJ 2482 Stars in Your Window(线段树)

    POJ 2482 Stars in Your Window 题目链接 题意:给定一些星星,每一个星星都有一个亮度.如今要用w * h的矩形去框星星,问最大能框的亮度是多少 思路:转化为扫描线的问题,每 ...

  6. poj 2482 Stars in Your Window(扫描线)

    id=2482" target="_blank" style="">题目链接:poj 2482 Stars in Your Window 题目大 ...

  7. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  8. 【POJ 2777】 Count Color(线段树区间更新与查询)

    [POJ 2777] Count Color(线段树区间更新与查询) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4094 ...

  9. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

随机推荐

  1. 【BZOJ3073】[Pa2011]Journeys 线段树+堆优化Dijkstra

    [BZOJ3073][Pa2011]Journeys Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在 ...

  2. F - 简单计算器(栈)

    F - 简单计算器 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descripti ...

  3. Java实现单例模式的两种方式

    单例模式在实际开发中有很多的用途,比如我们在项目中常用的工具类,数据库等资源的连接类.这样做的好处是避免创建多个对象,占用内存资源,自始自终在内存中只有一个对象为我们服务. 单例对象一般有两种实现方式 ...

  4. linux下安装nmon监控工具

    1.首先下载压缩包 wget http://sourceforge.net/projects/nmon/files/download/nmon_x86_12a.zip/download 2.解压并修改 ...

  5. float 的先后顺序 理解流

    <!DOCTYPE html><html><head><style> p{float:right;}</style></head> ...

  6. 虚拟研讨会:如何设计好的RESTful API(转)

    原文:虚拟研讨会:如何设计好的RESTful API? REST架构风格最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出.HTTP就是该架构风 ...

  7. br_netfilter 模块开机自动方法

    环境 cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 在/etc/sysctl.conf中添加: net.bridge.bri ...

  8. Maven学习笔记—坐标和依赖

    Maven的坐标和依赖 1 Maven坐标 1.1 什么是Maven坐标 Maven坐标:世界上任何一组构件都可以使用Maven坐标来唯一标识,Maven坐标的元素包括groupId.artifact ...

  9. 2015.7.2 想做T再次失败

    2015.7.2教训:不要心存侥幸! 1.昨天收盘急跌,加上看到成交量在增加,负荷庄家行为第五条,一时脑热就去抄了.其实在震荡行情下,第二天肯定有时间点比头一天的收盘价低(Pic1) 2.T+0原则: ...

  10. 流量分析系统----讲解-echarts模拟迁移(结合china.js)

    百度 Echarts 地图->模拟迁徙,实现自动切换地图 小航哥注释: 1.本文主要是把模拟迁移的流程讲了一遍,讲的很好.具体实现参考航哥这篇随笔“流量分析系统----实现-echarts模拟迁 ...