[线段树扫描线][USACO5.5]矩形周长Picture

Posted yuxiaoze

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线段树扫描线][USACO5.5]矩形周长Picture相关的知识,希望对你有一定的参考价值。

墙上贴着许多形状相同的海报、照片。它们的边都是水平和垂直的。每个矩形图片可能部分或全部的覆盖了其他图片。所有矩形合并后的边长称为周长。

所有矩形的边界。所有矩形顶点的坐标都是整数。

输入文件的第一行是一个整数N(0<=N<5000),表示有多少个矩形。接下来N行给出了每一个矩形左下角坐标和右上角坐标(所有坐标的数值范围都在-10000到10000之间)。

输出文件只有一个正整数,表示所有矩形的周长。

 

题解

  线段树扫描线  https://www.luogu.org/problemnew/solution/P1856

 维护的东西非常巧妙  注意覆盖标记不下传  因为只查询根节点

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=10000+5;
 6 int n;
 7 struct edgeint x,y,h,c;a[N];
 8 bool cmp(edge p,edge q) return p.h<q.h || (p.h==q.h&& p.c>q.c);
 9 
10 int tot,b[N];
11 inline int hehe(int x) return lower_bound(b+1,b+tot+1,x)-b; 
12 
13 struct pointint l,r,cov,cnt,len; bool lf,rf; t[4*N];
14 inline void pushup(int i,int l,int r)
15  if(t[i].cov)
16      t[i].len=t[i].r-t[i].l;
17       t[i].lf=t[i].rf=1;
18       t[i].cnt=1;
19      
20   else 
21      t[i].len=t[2*i].len+t[2*i+1].len;
22       t[i].lf=t[2*i].lf; t[i].rf=t[2*i+1].rf;
23       t[i].cnt=t[2*i].cnt+t[2*i+1].cnt;
24       if(t[2*i].rf && t[2*i+1].lf) t[i].cnt--;
25      
26  
27 void build(int i,int l,int r)
28  t[i].l=b[l]; t[i].r=b[r+1];
29   if(l==r) return;
30   int mid=l+r>>1;
31   build(2*i,l,mid); build(2*i+1,mid+1,r);    
32  
33 void change(int i,int l,int r,int p,int q,int v)
34  if(p<=l && r<=q) t[i].cov+=v; pushup(i,l,r); return;
35   int mid=l+r>>1;
36   if(p<=mid) change(2*i,  l,  mid,p,q,v);
37   if(mid<q)     change(2*i+1,mid+1,r,p,q,v);
38   pushup(i,l,r);
39   
40 int main() 
41 
42  scanf("%d",&n); int x1,y1,x2,y2;
43     
44  for(int i=1;i<=n;i++)    
45    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
46     a[2*i-1].x=a[2*i].x=x1; a[2*i-1].y=a[2*i].y=x2;
47     a[2*i-1].h=y1; a[2*i].h=y2;
48     a[2*i-1].c=1;  a[2*i].c=-1;
49     b[++tot]=x1; b[++tot]=x2;
50       
51  sort(a+1,a+2*n+1,cmp);    
52      
53  sort(b+1,b+tot+1); tot=unique(b+1,b+tot+1)-b-1;    
54 
55  build(1,1,tot-1); int ans=0,last=0;
56  
57  for(int i=1;i<=2*n;i++)
58    change(1,1,tot-1,hehe(a[i].x),hehe(a[i].y)-1,a[i].c);
59       
60       ans+=2*t[1].cnt*(a[i+1].h-a[i].h)+abs(t[1].len-last);
61       last=t[1].len;
62   
63  printf("%d\n",ans); 
64 return 0;    
65 

 

以上是关于[线段树扫描线][USACO5.5]矩形周长Picture的主要内容,如果未能解决你的问题,请参考以下文章

USACO5.5 矩形周长 Picture | 扫描线 + 线段树

luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树

luogu1856 [USACO5.5]矩形周长Picture

[HDOJ1828]Picture(扫描线,线段树,矩形并周长)

矩形面积并矩形面积交矩形周长并(线段树扫描线总结)(转载)

POJ 1177 Picture(线段树:扫描线求轮廓周长)