SGU 319 Kalevich Strikes Back(线段树+扫描线)
来源:互联网 发布:今日头条点赞软件下载 编辑:程序博客网 时间:2024/06/06 20:42
转载请注明出处,谢谢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
一直以为需要记录整个区间的历史覆盖信息,其实只需要通过我们之前得到的关系,覆盖他的父节点就行了。
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <vector>#define LL long long#define lson step<<1#define rson step<<1|1using 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[N];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[N];int pre[N];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[N];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;}
阅读全文
0 0
- SGU 319 Kalevich Strikes Back(线段树+扫描线)
- SGU 319 Kalevich Strikes Back(线段树+扫描线)
- SGU 319 Kalevich Strikes Back(线段树扫描线)
- sgu-319-Kalevich Strikes Back-线段树
- SGU 319: Kalevich Strikes Back
- SGU 319 Kalevich Strikes Back 线段树维护lazy 建树 + dfs
- Kalevich Strikes Back(扫描线求分块的面积)
- Kalevich Strikes Back
- sgu-234 Black-White King Strikes Back
- The Aqualizer Strikes Back!
- XST Strikes Back
- Malevich Strikes Back!
- SGU Inversions(线段树)
- 线段树[扫描线]
- 线段树+扫描线
- 线段树 扫描线
- 线段树扫描线
- 线段树-扫描线
- poj2114 Boatherds
- 网易笔试:交错01串
- CodeForces
- ARKit从入门到精通(1)-ARKit初体验
- #以应用为中心的无服务器PaaS将成主流
- SGU 319 Kalevich Strikes Back(线段树+扫描线)
- 内存溢出和内存泄漏的区别
- (dfs)迷宫探索
- Random 不重复
- Linux 初始 RAM磁盘(initrd)概述
- 轻松理解 Android Binder,只需要读这一篇
- Android通用标题栏
- eclipse配置字体、背景颜色
- asp.net 实现session过期跳转到首页