//和求矩形覆盖面积相似
//以每个星星为左下角建立一个W*H的矩形,把矩形的左右边离散出来,左边的线段权值为val,右边的线段权值为-val
//排序后,从左到右扫描
//注意在向上更新时,节点root的最大值应是2*root与2*root+1值的最大者
//向下更新
//注意建立矩形时,边可以超出int范围
//排序时,x相等则按val从大到小排
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 10005
#define inf 1234567890
typedef __int64 i64;
int n,m,t,width,heigth,maxf;
struct TNode
{
int l,r,maxval,add;
} node[8*N];
struct TPoint
{
int x,y,value;
}tp[N];
struct TLine
{
int value,yd,yu;
i64 x;
}line[2*N];
i64 ly[2*N];
int tot;
int find(i64 x)
{
int l=0,r=tot-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(ly[mid]==x) return mid;
else if(ly[mid]<x) l=mid+1;
else r=mid;
}
return -1;
}
bool cmp(TLine a,TLine b)
{
return a.x<b.x||(a.x==b.x&&a.value>b.value);
}
void init()
{
int i,j,k;
sort(ly,ly+m);
tot=unique(ly,ly+m)-ly;
for(i=m=0;i<n;i++)
{
int y1=find(tp[i].y*1ll)+1;
int y2=find(tp[i].y*1ll+heigth)+1;
line[m].x=tp[i].x*1ll,line[m].yd=y1,line[m].yu=y2,line[m].value=tp[i].value;
m++;
line[m].x=tp[i].x*1ll+width,line[m].yd=y1,line[m].yu=y2,line[m].value=-tp[i].value;
m++;
}
sort(line,line+m,cmp);
}
void build(int root,int l,int r)
{
int mid=(l+r)>>1,p=root<<1;
node[root].l=l,node[root].r=r;
node[root].maxval=node[root].add=0;
if(l==r) return ;
build(p,l,mid);
build(p+1,mid+1,r);
}
void insert(int root,int l,int r,int val)
{
int mid=(node[root].l+node[root].r)>>1,p=root<<1;
if(node[root].l==l&&node[root].r==r)
{
node[root].maxval+=val;
node[root].add+=val;
maxf=max(maxf,node[root].maxval);
return;
}
if(node[root].add)
{
node[p].maxval+=node[root].add;
node[p].add+=node[root].add;
node[p+1].add+=node[root].add;
node[p+1].maxval+=node[root].add;
node[root].add=0;
}
if(r<=mid) insert(p,l,r,val);
else if(l>mid) insert(p+1,l,r,val);
else
{
insert(p,l,mid,val);
insert(p+1,mid+1,r,val);
}
node[root].maxval=max(node[p].maxval,node[p+1].maxval);
maxf=max(node[root].maxval,maxf);
}
void solve()
{
int i,j,k;
build(1,1,tot);
maxf=-1;
for(i=0;i<m;i++)
{
insert(1,line[i].yd,line[i].yu,line[i].value);
}
printf("%d\n",maxf);
}
int main()
{
while(scanf("%d%d%d",&n,&width,&heigth)!=EOF)
{
int i,j,k;
width--,heigth--;
for(i=m=0;i<n;i++)
{
scanf("%d%d%d",&tp[i].x,&tp[i].y,&tp[i].value);
ly[m++]=tp[i].y*1ll;
ly[m++]=tp[i].y*1ll+heigth;
}
init();
solve();
}
return 0;
}
poj2482---线段树
最新推荐文章于 2021-04-02 23:25:49 发布