SGU 319 Kalevich Strikes Back(线段树+扫描线)
2013-04-17 11:19
302 查看
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents
by---cxlove
题意:给出若干个矩形,不相交,但是可能包含,这样整个平面被这n个矩形切割成n+1个部分,输出这n+1个部分的面积。
http://acm.sgu.ru/problem.php?contest=0&problem=319
所谓的线段树入门题,果然我只是入门水平。
通过扫描线,线段树记录一下区间覆盖,然后就能判断矩形的包含关系,通过关系就可以建立出一棵关系树。
然后遍历一下这棵树就行了。
开始一直不太会记录,如果插入的边权值为负,也就是矩形的上边。这样区间应该覆盖哪条边。。。233333
一直以为需要记录整个区间的历史覆盖信息,其实只需要通过我们之前得到的关系,覆盖他的父节点就行了。
by---cxlove
题意:给出若干个矩形,不相交,但是可能包含,这样整个平面被这n个矩形切割成n+1个部分,输出这n+1个部分的面积。
http://acm.sgu.ru/problem.php?contest=0&problem=319
所谓的线段树入门题,果然我只是入门水平。
通过扫描线,线段树记录一下区间覆盖,然后就能判断矩形的包含关系,通过关系就可以建立出一棵关系树。
然后遍历一下这棵树就行了。
开始一直不太会记录,如果插入的边权值为负,也就是矩形的上边。这样区间应该覆盖哪条边。。。233333
一直以为需要记录整个区间的历史覆盖信息,其实只需要通过我们之前得到的关系,覆盖他的父节点就行了。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <vector> #define LL long long #define lson step<<1 #define rson step<<1|1 using namespace std; const int N=60005; struct Frames{ int x1,y1,x2,y2; Frames(){} Frames(int _x1,int _y1,int _x2,int _y2){ x1=_x1,y1=_y1,x2=_x2,y2=_y2; } }frames ; struct Scanning_line{ int y,x1,x2,id; Scanning_line(){} Scanning_line(int _y,int _x1,int _x2,int _i){ y=_y,x1=_x1,x2=_x2,id=_i; } bool operator<(const Scanning_line s)const{ return y<s.y; } }line[N<<1]; struct Segment_tree{ int left,right; int cover; }L[N<<3]; int n,w,h,x[N<<1],tot=0; vector<int>edge ; int pre ; void bulid(int step,int l,int r){ L[step].left=l; L[step].right=r; L[step].cover=0; if(l==r) return ; int m=(l+r)>>1; bulid(lson,l,m); bulid(rson,m+1,r); } void push_down(int step){ if(L[step].cover!=-1){ L[lson].cover=L[rson].cover=L[step].cover; L[step].cover=-1; } } int query(int step,int l,int r){ if(L[step].cover!=-1) return L[step].cover; int m=(L[step].left+L[step].right)>>1; push_down(step); if(r<=m) return query(lson,l,r); else if(l>m) return query(rson,l,r); else return query(lson,l,m); } void update(int step,int l,int r,int id){ if(L[step].left==l&&L[step].right==r){ if(id<0){ L[step].cover=pre[abs(id)]; } else{ L[step].cover=id; } return ; } push_down(step); int m=(L[step].left+L[step].right)>>1; if(r<=m) update(lson,l,r,id); else if(l>m) update(rson,l,r,id); else{ update(lson,l,m,id); update(rson,m+1,r,id); } } LL area ; void dfs(int u){ for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; area[u]-=area[v]; dfs(v); } } int main(){ scanf("%d%d%d",&n,&w,&h); frames[0]=Frames(0,0,w,h); area[0]=(LL)w*h; for(int i=0;i<n;i++){ int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2); line[i*2]=Scanning_line(y1,x1,x2,i+1); line[i*2+1]=Scanning_line(y2,x1,x2,-(i+1)); x[tot++]=x1; x[tot++]=x2; frames[i+1]=Frames(x1,y1,x2,y2); area[i+1]=(LL)(x2-x1)*(y2-y1); } x[tot++]=0;x[tot++]=w; sort(x,x+tot); tot=unique(x,x+tot)-x; bulid(1,0,tot-1); sort(line,line+2*n); for(int i=0;i<2*n;i++){ line[i].x1=lower_bound(x,x+tot,line[i].x1)-x; line[i].x2=lower_bound(x,x+tot,line[i].x2)-x; if(line[i].id>0){ pre[line[i].id]=query(1,line[i].x1,line[i].x2); edge[pre[line[i].id]].push_back(line[i].id); } update(1,line[i].x1,line[i].x2,line[i].id); } dfs(0); sort(area,area+n+1); for(int i=0;i<=n;i++) printf("%lld%c",area[i],i==n?'\n':' '); return 0; }
相关文章推荐
- SGU 319 Kalevich Strikes Back(线段树+扫描线)
- SGU 319 Kalevich Strikes Back 线段树维护lazy 建树 + dfs
- SGU 319 Kalevich Strikes Back(线段树扫描线)
- SGU 319 Kalevich Strikes Back(线段树扫描线)
- SGU 319: Kalevich Strikes Back
- sgu-319-Kalevich Strikes Back-线段树
- sgu-234 Black-White King Strikes Back
- Kalevich Strikes Back(扫描线求分块的面积)
- Kalevich Strikes Back
- SGU 319. Kalevich Strikes Back (线段树)
- SGU 234 Black-White King Strikes Back(二分图匹配)
- Codeforces Round #181 (Div. 2) E. Empire Strikes Back N!∣∏K,i=1ai!
- CF 300E Empire Strikes Back
- sgu234:Black-White King Strikes Back(二分图匹配)
- XST Strikes Back
- Codeforces Round #181 (Div. 2) E. Empire Strikes Back N!∣∏K,i=1ai!
- sgu 197 Nice Patterns Strike Back 矩阵快速幂
- The Aqualizer Strikes Back!
- 刷清橙OJ--A1055."The Next Cow"Strikes Back
- Codeforces Round #181 (Div. 2) E. Empire Strikes Back N!∣∏K,i=1ai!