POJ 1177 Picture(矩形并的周长)
2016-03-26 12:10
507 查看
题目链接:
POJ 1177 Picture
POJ 1177 Picture
//926K 16MS #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #define lson(x) (x<<1) #define rson(x) ((x<<1)|1) using namespace std; const int maxn=5050; int n,x1,x2,yy1,y2; int xx[maxn<<2]; struct SegTree{ int left,right,len,num,flag;//len是有效长度,num是有几条线段,flag记录状态 bool lcover,rcover;//记录区间左右端点是否存在竖边 }segtree[maxn<<4]; struct Line{ int x1,x2,y,flag; bool operator < (const Line a) const{ return y<a.y; } }line[maxn<<2]; void build(int left,int right,int cur) { segtree[cur].left=left; segtree[cur].right=right; segtree[cur].len=segtree[cur].num=segtree[cur].flag=0; segtree[cur].lcover=segtree[cur].rcover=false; if(left+1==right) return ; int mid=(left+right)>>1; build(left,mid,lson(cur)); build(mid,right,rson(cur)); } void calc_len(int cur) { int left=segtree[cur].left; int right=segtree[cur].right; if(segtree[cur].flag>0){ segtree[cur].len=xx[right]-xx[left]; segtree[cur].num=1; segtree[cur].lcover=segtree[cur].rcover=true; }else if(left+1==right){ segtree[cur].len=segtree[cur].num=0; segtree[cur].lcover=segtree[cur].rcover=false; }else{ segtree[cur].len=segtree[lson(cur)].len+segtree[rson(cur)].len; segtree[cur].num=segtree[lson(cur)].num+segtree[rson(cur)].num; segtree[cur].lcover=segtree[lson(cur)].lcover; segtree[cur].rcover=segtree[rson(cur)].rcover; if(segtree[lson(cur)].rcover&&segtree[rson(cur)].lcover)//左右儿子的线段可以衔接 segtree[cur].num--;//合并成一个线段,所以线段数量-1 } return; } void update(int a,int b,int flag,int cur) { int left=segtree[cur].left; int right=segtree[cur].right; if(left==a&&right==b){ segtree[cur].flag+=flag; calc_len(cur); return; } int mid=(left+right)>>1; if(b<=mid) update(a,b,flag,lson(cur)); else if(a>=mid) update(a,b,flag,rson(cur)); else{ update(a,mid,flag,lson(cur)); update(mid,b,flag,rson(cur)); } calc_len(cur); } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif while(~scanf("%d",&n)){ int tot=0; for(int i=0;i<n;i++){ scanf("%d %d %d %d",&x1,&yy1,&x2,&y2); line[tot].x1=x1,line[tot].x2=x2,line[tot].y=yy1,line[tot].flag=1; line[tot+1].x1=x1,line[tot+1].x2=x2,line[tot+1].y=y2,line[tot+1].flag=-1; xx[tot]=x1,xx[tot+1]=x2; tot+=2; } sort(xx,xx+tot); int m=unique(xx,xx+tot)-xx; build(0,m-1,1); sort(line,line+tot); int ans=0,last=0,a,b; for(int i=0;i<tot-1;i++){ a=lower_bound(xx,xx+m,line[i].x1)-xx; b=lower_bound(xx,xx+m,line[i].x2)-xx; update(a,b,line[i].flag,1); ans+=(line[i+1].y-line[i].y)*segtree[1].num*2;//竖边数量是线段数量的两倍 ans+=abs(segtree[1].len-last); //因为加上边时flag为-1,这时线段树中这条边就不存在了,但是求周长时是应该加上的 //而且在上一棵线段树中是有的,所以要用abs last=segtree[1].len; } a=lower_bound(xx,xx+m,line[tot-1].x1)-xx; b=lower_bound(xx,xx+m,line[tot-1].x2)-xx; update(a,b,line[tot-1].flag,1); ans+=abs(segtree[1].len-last); printf("%d\n",ans); } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- 线段树题集
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 线段树
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)