【IOI1998】Picture(扫描线+线段树)

问题来源:IOI1998 D2T1

题意:就是在一个平面内给出n个矩形,叫你计算将这些矩形合并以后,新图形的周长。

例如:

上图是原本的矩形们      ---------->合并后的图形

解题思路:拿一条扫描线横着扫一次,遇到左边的边就在这条扫描线上+1,遇到右边的边就在这条扫描线上-1,在边被扫到的时候计算一下线上为0的个数即可。

  因为如果只是单纯的For循环累加,时间会爆,所以我们采用线段树来存这条扫描线的状态优化效率即可。然后竖着再做同样的事做一遍。

  时间效率应该是O(kn)(k是常数)。

附代码:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 #define For(i,a,b) for (int i=a; i<=b; i++)
  8 #define Ford(i,a,b) for (int i=a; i>=b; i--)
  9 #define File(fn) freopen(fn".in","r",stdin); freopen(fn".out","w",stdout);
 10 #define mem(qaq,num) memset(qaq,num,sizeof(qaq));
 11 #define ll long long
 12 #define mod 1000000007
 13 #define INF 2000000000
 14 #define mid ((l+r)>>1)
 15 using namespace std;
 16 struct zxy{
 17     int mi,n,mark;
 18 }tr[65540];
 19 struct edge{
 20     int l,r,h,typ;
 21 }x[10001],y[10001];
 22 int n,ans,cnt;
 23 inline int in(){
 24     int x=0,f=1;
 25     char ch=getchar();
 26     while (ch<'0'||ch>'9') f=ch=='-'?-1:1,ch=getchar();
 27     while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
 28     return x*f;
 29 }
 30 inline void combine(int k){
 31     if (tr[k<<1].mi==tr[k<<1|1].mi) tr[k].n=tr[k<<1].n+tr[k<<1|1].n,tr[k].mi=tr[k<<1].mi;
 32     else 
 33         if(tr[k<<1].mi<tr[k<<1|1].mi) tr[k].n=tr[k<<1].n,tr[k].mi=tr[k<<1].mi;
 34         else tr[k].n=tr[k<<1|1].n,tr[k].mi=tr[k<<1|1].mi;
 35     return;
 36 }
 37 inline void built(int l,int r,int k){
 38     if (l==r){
 39         tr[k].mi=0;
 40         tr[k].n=1;
 41         tr[k].mark=0;
 42         return;
 43     }
 44     built(l,mid,k<<1);
 45     built(mid+1,r,k<<1|1);
 46     combine(k);
 47     tr[k].mark=0;
 48 }
 49 inline void pushdown(int k){
 50     int ad=tr[k].mark;
 51     tr[k<<1].mark+=ad;
 52     tr[k<<1|1].mark+=ad;
 53     tr[k<<1].mi+=ad;
 54     tr[k<<1|1].mi+=ad;
 55     tr[k].mark=0;
 56     return;
 57 }
 58 inline void update(int l,int r,int a,int b,int k,int ad){
 59     if (l>=a&&b>=r){
 60         tr[k].mark+=ad;
 61         tr[k].mi+=ad;
 62         return;
 63     }
 64     if (tr[k].mark) pushdown(k);
 65     if (a<=mid) update(l,mid,a,b,k<<1,ad);
 66     if (b>mid) update(mid+1,r,a,b,k<<1|1,ad);
 67     combine(k);
 68     return;
 69 }
 70 inline int query(int l,int r,int k,int a,int b){
 71     if (l==a&&r==b){
 72         if (tr[k].mi) return 0;
 73         return tr[k].n;
 74     }
 75     if (tr[k].mark) pushdown(k);
 76     if (b<=mid) return query(l,mid,k<<1,a,b);
 77     if (a>mid) return query(mid+1,r,k<<1|1,a,b);
 78     return query(l,mid,k<<1,a,mid)+query(mid+1,r,k<<1|1,mid+1,b);
 79 }
 80 void init(){
 81     n=in();
 82     For(i,1,n){
 83         int x1=in()+10001,y1=in()+10001,x2=in()+10001,y2=in()+10001;
 84         x[++cnt].l=x1+1,x[cnt].r=x2,x[cnt].h=y1,x[cnt].typ=0;
 85         y[cnt].l=y1+1,y[cnt].r=y2,y[cnt].h=x1,y[cnt].typ=0;
 86         x[++cnt].l=x1+1,x[cnt].r=x2,x[cnt].h=y2,x[cnt].typ=1;
 87         y[cnt].l=y1+1,y[cnt].r=y2,y[cnt].h=x2,y[cnt].typ=1;
 88     }
 89     return;
 90 }
 91 bool cmp(edge a,edge b){
 92     return a.h<b.h||(a.h==b.h&&a.typ<b.typ);
 93 }
 94 void work(){
 95     sort(x+1,x+cnt+1,cmp);
 96     built(1,20001,1);
 97     For(i,1,cnt)
 98         if (!x[i].typ){            
 99             ans+=query(1,20001,1,x[i].l,x[i].r);    
100             update(1,20001,x[i].l,x[i].r,1,1);
101         }
102         else{
103             update(1,20001,x[i].l,x[i].r,1,-1);
104             ans+=query(1,20001,1,x[i].l,x[i].r);
105         }
106     sort(y+1,y+cnt+1,cmp);
107     built(1,20001,1);
108     For(i,1,cnt)
109         if (!y[i].typ){
110             ans+=query(1,20001,1,y[i].l,y[i].r);
111             update(1,20001,y[i].l,y[i].r,1,1);
112         }
113         else{
114             update(1,20001,y[i].l,y[i].r,1,-1);
115             ans+=query(1,20001,1,y[i].l,y[i].r);
116         }
117     return;
118 }
119 int main(){
120     init();
121     work();
122     printf("%d",ans);
123 }

 本文由Melacau编写,Melacau代表M星向您问好,如果您不是在我的博客http://www.cnblogs.com/Melacau上看到本文,请您向我联系,email:13960948839@163.com.

posted @ 2017-03-06 09:25  Melacau  阅读(826)  评论(0编辑  收藏  举报