poj2482Stars in Your Window(线段树+离散化+扫描线)

时间:2023-03-08 21:47:23
poj2482Stars in Your Window(线段树+离散化+扫描线)

http://poj.org/problem?id=2482

类似于上一篇 这题转化的比较巧妙 将一个点转化为一个矩形(x,y, x+w,y+h),扫描线入值为正 出值为负

也就是一根线过去 每进入一个矩形 都更新线上的总值 取一个最大值

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define N 20010
#define LL long long
struct node
{
LL lx,rx,y,s;
node(){}
node(LL a,LL b,LL c,LL d):lx(a),rx(b),y(c),s(d){}
bool operator <(const node &S)const
{
if(y==S.y)
return s>S.s;
return y<S.y;
}
}te[N];
int sum[N<<],cov[N<<],que[N];
int bin(LL x,int n)
{
int s=,e = n,m;
while(s<=e)
{
m = (s+e)/;
if(que[m]==x)
return m;
else if(que[m]>x)
e = m-;
else
s = m+;
}
return m;
}
void pushdown(int w)
{
if(cov[w])
{
cov[w<<] += cov[w];
cov[w<<|] += cov[w];
sum[w<<] += cov[w];
sum[w<<|] += cov[w];
cov[w] = ;
}
}
void pushup(int w)
{
sum[w] = max(sum[w<<],sum[w<<|]);
}
void update(int a,int b,int d,int l,int r,int w)
{
if(a<=l&&b>=r)
{
sum[w]+=d;
cov[w]+=d;
return ;
}
pushdown(w);
int m = (l+r)>>;
if(a<=m)
update(a,b,d,l,m,w<<);
if(b>m)
update(a,b,d,m+,r,w<<|);
pushup(w);
}
int main()
{
int i,k,n;
LL w,h,x,y,v;
while(cin>>n>>w>>h)
{
int num = ;
w--;h--;
for(i = ; i <= n ;i++)
{
cin>>x>>y>>v;
que[num] = x;
te[num++] = node(x,x+w,y,v);
que[num] = x+w;
te[num++] = node(x,x+w,y+h,-v);
}
sort(que,que+num);
sort(te,te+num);
k = ;
for(i = ; i < num ; i++)
{
if(que[i]!=que[i-])
que[k++] = que[i];
}
int maxz = ;
for(i = ; i < num ; i++)
{
int l = bin(te[i].lx,k-);
int r = bin(te[i].rx,k-);
update(l,r,te[i].s,,k-,);
maxz = max(maxz,sum[]);
}
cout<<maxz<<endl;
}
return ;
}