poj 2482 Stars in Your Window(线段树+离散化+线扫描)
2013-06-22 21:05
549 查看
题目:http://poj.org/problem?id=2482
大意:在一个坐标系中给你n(10^4)个点(点的坐标范围为0<=x,y<2^31),每个点有一个权值,然后给你一个长宽分别为w,h(10^6)的矩形(平行于坐标轴);
现在你的任务就是求出用这个矩形所覆盖的点的权值和的最大值(矩形边上的点不算)(矩形可以平移但是不能旋转)
思路:每个星星都可以以它自己为矩形的左下角(不能包括矩形边),那么就有n个矩形,就转化成了黑书上的第108页的题目,即统计所有1x1的小方格被覆盖的矩形最多的;
由于点的数量很小,但是坐标的范围很大,于是需要离散化;
自左向右扫描,左右竖线(在程序中用正负表示)标志矩形进入和退出阴影区域,利用线段树进行更新;
代码:
View Code
大意:在一个坐标系中给你n(10^4)个点(点的坐标范围为0<=x,y<2^31),每个点有一个权值,然后给你一个长宽分别为w,h(10^6)的矩形(平行于坐标轴);
现在你的任务就是求出用这个矩形所覆盖的点的权值和的最大值(矩形边上的点不算)(矩形可以平移但是不能旋转)
思路:每个星星都可以以它自己为矩形的左下角(不能包括矩形边),那么就有n个矩形,就转化成了黑书上的第108页的题目,即统计所有1x1的小方格被覆盖的矩形最多的;
由于点的数量很小,但是坐标的范围很大,于是需要离散化;
自左向右扫描,左右竖线(在程序中用正负表示)标志矩形进入和退出阴影区域,利用线段树进行更新;
代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=10010; struct node { __int64 id;//坐标值 int flag;//标记左边还是右边 int xh;//序号 }sx[maxn*2],sy[maxn*2]; struct bj { int y1,y2; int val;//左进右出,左为正,有为负 }line[maxn*2]; int n; int tree[maxn*8]; int lz[maxn*8];//懒惰标记 bool cmp(struct node a,struct node b) { if(a.id==b.id) return a.flag>b.flag; return a.id<b.id; } void disper()//离散化 { sort(sx,sx+(n<<1),cmp); sort(sy,sy+(n<<1),cmp); int temp=sy[0].id; int tg=1; int i; for(i=0;i<n*2;i++) { if(temp!=sy[i].id) { tg++; temp=sy[i].id; } if(sy[i].flag) { line[sy[i].xh*2].y2=tg; line[sy[i].xh*2+1].y2=tg; } else { line[sy[i].xh*2].y1=tg; line[sy[i].xh*2+1].y1=tg; } } } void build(int l,int r,int w) { tree[w]=0; lz[w]=0; if(l==r) { return ; } int m=(l+r)>>1; build(l,m,w<<1); build(m+1,r,w<<1|1); } void update(int l,int r,int w,int L,int R,int val) { if(L<=l&&R>=r) { tree[w]+=val; lz[w]+=val;//延迟标记 return ; } if(lz[w]!=0)//取消标记 { lz[w<<1|1]+=lz[w]; lz[w<<1]+=lz[w]; tree[w<<1]+=lz[w]; tree[w<<1|1]+=lz[w]; lz[w]=0; } int m=(l+r)>>1; if(L>m) update(m+1,r,w<<1|1,L,R,val); else if(R<=m) update(l,m,w<<1,L,R,val); else { update(l,m,w*2,L,m,val); update(m+1,r,w<<1|1,m+1,R,val); } tree[w]=max(tree[w<<1],tree[w<<1|1]); } int main() { int w,h; while(scanf("%d%d%d",&n,&w,&h)!=EOF) { int i; __int64 x,y; int valu; for(i=0;i<n;i++) { scanf("%I64d%I64d%d",&x,&y,&valu); sx[i<<1].id=x; sx[i<<1].flag=0;//左边 sx[i<<1|1].id=x+w; sx[i<<1|1].flag=1;//右边 sx[i<<1|1].xh=sx[i<<1].xh=i; sy[i<<1].id=y; sy[i<<1].flag=0; sy[i<<1|1].id=y+h; sy[i<<1|1].flag=1; sy[i<<1|1].xh=sy[i<<1].xh=i; line[i<<1].val=valu; line[i<<1|1].val=-valu; } disper();//离散化 /*for(i=0;i<n*2;i++) { printf("%d %d %d\n",line[i].yd,line[i].yu,line[i].val); }*/ n=n*2; build(1,n,1); int id; int ans=0; for(i=0;i<n;i++)//扫描 { id=sx[i].xh*2+sx[i].flag; line[id].y1++;//不包括边 update(1,n,1,line[id].y1,line[id].y2,line[id].val); if(ans<tree[1]) ans=tree[1]; } printf("%d\n",ans); } return 0; }
View Code
相关文章推荐
- POJ 2482 Stars in Your Window 离散化+扫描法 线段树应用
- POJ_2482_Stars in Your Window_线段树、离散化处理
- POJ 2482 Stars in Your Window 线段树+离散化+扫描线
- POJ-2482-Stars in Your Window(线段树,扫描线)
- poj2482 Stars in Your Window hdu 5091 Beam Cannon 线段树 扫描线
- POJ 2482——Stars in Your Window(线段树+扫描线,二维区域最值转化为线段树-经典)最浪漫的题目
- POJ 题目2482 Stars in Your Window(线段树+离散化)
- POJ 2482 Stars in Your Window(离散化+线段树:扫描线)
- poj2482 Stars in Your Window(线段树+扫描线+离散化)
- POJ 2482 stars in your window(线段树 , 扫描线)
- POJ 2482 Stars in Your Window【离散化+扫描线+线段树
- poj 2482 Stars in Your Window(线段树+扫描线+离散化)
- POJ 2482 Stars in Your Window(扫描线 + 线段树 区域统计)
- poj 2482 Stars in Your Window 线段树 扫描线
- poj 2482 Stars in Your Window (线段树+平面扫描)
- poj 2482 Stars in Your Window(线段树,扫描线)
- POJ 2482 Stars in Your Window【扫描线+离散化】
- poj 2482 Stars in Your Window 扫描线 线段树
- POJ2482 Stars in Your Window 线段树 二维转换一维 STL
- POJ 2482 Stars in Your Window(扫描线)