您的位置:首页 > 其它

poj 2482 Stars in Your Window 线段树

2014-11-25 00:24 417 查看
传送门:poj 2482

好长的题目,结果前面的情书都可以不看,简单来说就是求给定大小的矩形中能包含到的星星的亮度的最大值,在矩形左边沿与下边沿的星星可行,上边沿与右边沿的不算

想了好久好久,在搜了题解之后总算是弄明白了

这里运用到了转化的思想,将每个点分别转化成为两条线段,线段有个权值,利用线段对线段树进行成段更新。每个星星的x坐标用来排序,记录添加线段的顺序,每个星星分出两条线段,一条x,更新的值为val,即星星的亮度一条x+w,更新的值为-val。每条线段更新的长度为从y到y+h-1,这里的x,y的值很大,因此需要对所有可能出现的y值进行离散化处理。最终在更新线段树的过程中,记录当前可能得到的最大值,即为最后的结果

/******************************************************
* File Name:   2482.cpp
* Author:      kojimai
* Create Time: 2014年11月24日 星期一 16时56分49秒
******************************************************/

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define FFF 23333
long long y[FFF];
struct node
{
long long x,c,y1,y2;
}p[FFF];
bool cmp(node a,node b) {
if(a.x == b.x)
return a.c < b.c;
return a.x < b.x;
}
struct nod {
long long l,r;
long long sum,down;
}pp[FFF*4];

void build(long long l,long long r,int num) {
pp[num].l = l; pp[num].r = r; pp[num].sum = 0; pp[num].down = 0;
if(l == r)
return;
int mid = (l + r) >> 1;
build(l,mid,num*2);
build(mid+1,r,num*2+1);
}

void solve(int num,long long val)
{
pp[num*2].sum += val;
pp[num*2].down += val;
pp[num*2+1].sum += val;
pp[num*2+1].down += val;
pp[num].down = 0;
}
long long update(long long left,long long right,long long c,int num) {
//cout<<" left = "<<left<<" right = "<<right<<" c = "<<c<<" num = "<<num<<" l = "<<pp[num].l<<" r = "<<pp[num].r<<endl;
if(left == y[pp[num].l] && right == y[pp[num].r]) {
pp[num].sum += c;
pp[num].down += c;
//cout<<" num = "<<num<<" sum = "<<pp[num].sum<<endl;
return pp[num].sum;
}
if(pp[num].l == pp[num].r) {
return pp[num].sum;
}
if(pp[num].down != 0)
solve(num,pp[num].down);
int mid = (pp[num].l + pp[num].r) >> 1;
if(y[mid] >= right)
pp[num].sum = max(update(left,right,c,num*2),pp[num*2+1].sum);
else if(y[mid] < left)
pp[num].sum = max(pp[num*2].sum,update(left,right,c,num*2+1));
else
pp[num].sum = max(update(left,y[mid],c,num*2),update(y[mid+1],right,c,num*2+1));
//	cout<<" num = "<<num<<" sum = "<<pp[num].sum<<endl;
return pp[num].sum;
}

int main()
{
long long n,w,h;
while(cin>>n>>w>>h)
{
for(long long i = 0;i < n;i++)
{
cin>>p[i*2].x>>p[i*2].y1>>p[i*2].c;
y[i*2+1] = p[i*2].y1; y[i*2+2] = p[i*2].y1 + h - 1;
p[i*2].y2 = p[i*2].y1 + h - 1;
p[i*2+1].x = p[i*2].x + w;
p[i*2+1].y1 = p[i*2].y1;
p[i*2+1].y2 = p[i*2].y2;
p[i*2+1].c = -p[i*2].c;
}
sort(y+1,y+2*n+1);
sort(p,p+2*n,cmp);
int cnt = unique(y+1,y+2*n+1)-y-1;
build(1,cnt,1);

long long ans = 0,t;
for(int i = 0;i < 2*n;i++) {
//cout<<"x1 = "<<p[i].x<<' ';
//cout<<"y1 = "<<p[i].y1<<" y2 = "<<p[i].y2<<" c = "<<p[i].c<<endl;
t = update(p[i].y1,p[i].y2,p[i].c,1);
//cout<<" t = "<<t<<endl;
ans = max(t,ans);
}
cout<<ans<<endl;;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: