POJ 2482 线段树 扫描线

来源:互联网 发布:ntfs for mac 10.9.1 编辑:程序博客网 时间:2024/06/14 10:50

扫描线问题很好的应用

把每个星星转化成w*h的矩阵,在x,y+h的位置再添加一个权值-value的星星。

按Y轴建树,X轴扫描一遍


#include "iostream"#include "algorithm"using namespace std;struct comp{int x,y,value;} node[10010];__int64  y[10010]; struct comp1{__int64 l,r,mid;__int64 max,add;} data[80010];bool cmp(comp a,comp b){return a.x<b.x;}__int64 max(__int64 a, __int64 b){if (a<b) return b;else return a;}void build(__int64 l,__int64 r,int k){data[k].l=l;data[k].r=r;data[k].mid=(l+r)/2;data[k].max=data[k].add=0;if (l==r) return ;build(l,data[k].mid,k*2);build(data[k].mid+1,r,k*2+1);}void updata(__int64 l,__int64 r,int k,__int64 c){if (data[k].l==l && data[k].r==r){data[k].add+=c;data[k].max+=c;return ;}if (data[k].add){data[k*2].add+=data[k].add;data[k*2].max+=data[k].add;data[k*2+1].add+=data[k].add;data[k*2+1].max+=data[k].add;data[k].add=0;}if (r<=data[k].mid) updata(l,r,k*2,c);else if (l>data[k].mid) updata(l,r,k*2+1,c);else {updata(l,data[k].mid,k*2,c);updata(data[k].mid+1,r,k*2+1,c);}data[k].max=max(data[k*2].max,data[k*2+1].max);}__int64 len;__int64 find(__int64 x){__int64 mid,l,r;l=0;r=len;while (l<=r){mid=(l+r)/2;if (y[mid]<x) l=mid+1;else if (y[mid]==x) return mid;else r=mid-1;}return l;}int main(){int n,i,j,ll,rr;__int64 max,w,h;while (scanf("%d%I64d%I64d",&n,&w,&h)!=EOF){for (i=0;i<n;i++){scanf("%I64d%I64d%I64d",&node[i].x,&node[i].y,&node[i].value);y[i]=node[i].y;}sort(node,node+n,cmp);sort(y,y+n);len=1;for (i=1;i<n;i++)if (y[i]!=y[i-1])y[len++]=y[i];len--;build(0,len,1);max=0;for (i=0,j=0;i<n;i++){while (node[i].x-node[j].x>=w) // 若超出矩阵范围则插入-value值{ll=find(node[j].y);rr=find(node[j].y+h)-1;updata(ll,rr,1,-node[j].value);j++;}ll=find(node[i].y);rr=find(node[i].y+h)-1;updata(ll,rr,1,node[i].value);if (data[1].max>max) max=data[1].max;}printf("%I64d\n",max);}return 0;}


原创粉丝点击