POJ 2482 Stars in Your Window(掃描線)

來源:互聯網
上載者:User

題意:給你10000以內的星星的座標和星星的亮度(即分別為x,y,c),要求用W*H的矩形去圍住一個地區,使得這個地區內的星星的亮度最大,並且要求矩形邊框上的星星不計入內。矩形可以平移,但不能旋轉。

對於每一個星星,分別建立線(x,y,y+H,c)和(x+W,y,y+H,-c)。這樣處理的原因是我們就可以把問題轉化成求線段樹裡某一段內的最大值,即區間查詢。矩形邊框上的星星不計的處理方法是:1.對於x軸方面的處理是在排序的時候,優先-c的邊,因為如果優先+c的邊,那麼就是將邊框上的星星計入了。2.對於y軸方面的,我的處理方法是將線段樹的葉子結點處理成長度為1的區間即[0,1],[1,2]。。。這樣,那麼在處理比如覆蓋範圍是在(0,1),(1,2)的邊時,就能避免邊框的問題,即點2不會被兩個邊更新到,因為更新的是長度為1的區間。要用離散化。

/*代碼風格更新後*/#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <map>#include <algorithm>using namespace std;#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))const int N=20005;typedef long long LL;struct Line{LL x,y1,y2,valu;Line(){}Line(LL a,LL b,LL c,LL d){ x=a;y1=b;y2=c;valu=d; }bool operator<(const Line&b)const{return x<b.x||(x==b.x&&valu<b.valu);}};struct node{int lft,rht;int flag,mx;int mid(){return MID(lft,rht);}void fun(int valu){mx+=valu;flag+=valu;}};vector<LL> y;vector<Line> line;map<LL,int> H;struct Segtree{node tree[N*4];void build(int lft,int rht,int ind){tree[ind].lft=lft;tree[ind].rht=rht;tree[ind].mx=0;tree[ind].flag=0;if(lft+1!=rht){int mid=tree[ind].mid();build(lft,mid,LL(ind));build(mid,rht,RR(ind));}}void updata(int st,int ed,int ind,int valu){int lft=tree[ind].lft,rht=tree[ind].rht;if(st<=lft&&rht<=ed) tree[ind].fun(valu);else {if(tree[ind].flag){tree[LL(ind)].fun(tree[ind].flag);tree[RR(ind)].fun(tree[ind].flag);tree[ind].flag=0;}int mid=tree[ind].mid();if(st<mid) updata(st,ed,LL(ind),valu);if(ed>mid) updata(st,ed,RR(ind),valu);tree[ind].mx=max(tree[LL(ind)].mx,tree[RR(ind)].mx);}}}seg;int main(){int n,w,h;while(scanf("%d%d%d",&n,&w,&h)!=EOF){y.clear(); H.clear(); line.clear();for(int i=0;i<n;i++){LL a,b,c;scanf("%lld%lld%lld",&a,&b,&c);line.push_back(Line(a,b,b+h,c));line.push_back(Line(a+w,b,b+h,-c));y.push_back(b); y.push_back(b+h); }sort(line.begin(),line.end());sort(y.begin(),y.end());y.erase(unique(y.begin(),y.end()),y.end());for(int i=0;i<(int)y.size();i++) H[y[i]]=i;int mx=0;seg.build(0,(int)y.size()-1,1);for(int i=0;i<(int)line.size();i++){seg.updata(H[line[i].y1],H[line[i].y2],1,line[i].valu);mx=max(mx,seg.tree[1].mx);}printf("%d\n",mx);}return 0;}

#include <iostream>/*代碼風格更新前*/#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N=20005;LL order[N];struct Line{    LL x,y1,y2;    int valu;    Line(){}    Line(LL a,LL b,LL c,int d){x=a;y1=b;y2=c;valu=d;}    bool operator < (const Line &b) const {        return x<b.x||(x==b.x&&valu<b.valu);    }}line[N];struct node{int left,right;int iadd,imax;int mid(){return left+(right-left)/2;}void change(int valu){iadd+=valu;imax+=valu;}};struct Segtree{node tree[N*4];void clear(){memset(tree,0,sizeof(tree));}void build(int left,int right,int ind){tree[ind].left=left;tree[ind].right=right;tree[ind].iadd=0;tree[ind].imax=0;if(left+1!=right){int mid=tree[ind].mid();build(left,mid,ind*2);build(mid,right,ind*2+1);}}void updata(int be,int end,int ind,int valu){int left=tree[ind].left,right=tree[ind].right;if(be<=left&&right<=end) tree[ind].change(valu);else {if(tree[ind].iadd)//懶操作,相當於push_down{tree[ind*2].change(tree[ind].iadd);tree[ind*2+1].change(tree[ind].iadd);tree[ind].iadd=0;}int mid=tree[ind].mid();if(be<mid) updata(be,end,ind*2,valu);if(end>mid) updata(be,end,ind*2+1,valu);tree[ind].imax=max(tree[ind*2].imax,tree[ind*2+1].imax);}}}seg;int main(){int n,w,h;while(scanf("%d%d%d",&n,&w,&h)!=EOF){int res=0;seg.clear();for(int i=0;i<n;i++){int x,y,valu;scanf("%d%d%d",&x,&y,&valu);order[i*2]=y;order[i*2+1]=(LL)y+h;line[i*2]=Line(x,y,(LL)y+h,valu);line[i*2+1]=Line((LL)x+w,y,(LL)y+h,-valu);}sort(line,line+n*2);sort(order,order+n*2);int cnt=unique(order,order+n*2)-order;seg.build(0,cnt,1);for(int i=0;i<n*2;i++){int y1=lower_bound(order,order+cnt,line[i].y1)-order;int y2=lower_bound(order,order+cnt,line[i].y2)-order;seg.updata(y1,y2,1,line[i].valu);res=max(res,seg.tree[1].imax);}printf("%d\n",res);}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.