线段树区间扫描线(hdu 1542)

题意描述:

给定一个矩阵,输入为左上角和右下角,现在要计算出所有矩阵重叠之后的面积总和。

 

解题思路:

根据x轴或者y轴建树,不过数据如果够大,必须先离散化,利用扫描线记录当前区间已经被覆盖的长度,那么现在覆盖的长度乘以下一条线段的距离,这个面积则是我们需要累加的面积。

其中的测试数据计算过程如下:

View Code
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 using std::sort;
 7 using std::unique;
 8 const int N = 2222;
 9 struct node
10 {
11        double y,lx,rx;
12        int s;
13        bool operator <(const node &tmp)const{
14            return y<tmp.y;
15        }
16 }line[N<<4];
17 double X[N<<4],sum[N<<4];
18 int cnt[N<<4];
19 void update(int t,int l,int r,int L,int R,int val)
20 {
21     if(L<=l&&r<=R)
22     {

23         cnt[t]+=val;
24         if(cnt[t])sum[t]=X[r+1]-X[l];
25         else
26            if(l==r)sum[t]=0;
27            else sum[t]=sum[t<<1]+sum[t<<1|1];
28         return ;
29     }
30     int m=(l+r)>>1;
31     if(L<=m)update(t<<1,l,m,L,R,val);
32     if(R>m)update(t<<1|1,m+1,r,L,R,val);
33     if(cnt[t])sum[t]=X[r+1]-X[l];
34         else
35            if(l==r)sum[t]=0;
36            else sum[t]=sum[t<<1]+sum[t<<1|1];
37 }
38 int Fin(double k,int len)
39 {
40     int l=0,r=len-1;
41     while(l<r)
42     {
43          int m=(l+r)>>1;
44          if(X[m]==k)return m;
45          if(X[m]>k)r=m-1;
46          else l=m+1;
47     }
48     return l;
49 }
50 int main()
51 {
52     int n,T=0;
53     double x1,x2,y1,y2;
54     while(scanf("%d",&n)&&n)
55     {
56         int top=0,i,j;
57         for(i=0,j=0;i<n;i++,j+=2)
58         {
59             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
60             X[top++]=x1,X[top++]=x2;
61             line[j].y=y1,line[j].lx=x1,line[j].rx=x2,line[j].s=1;
62             line[j+1].y=y2,line[j+1].lx=x1,line[j+1].rx=x2,line[j+1].s=-1;
63         }
64         sort(X,X+top);
65         top=unique(X,X+top)-X;
66         sort(line,line+j);
67         int l,r;
68         double answer=0;
69         memset(cnt,0,sizeof(cnt));
70         memset(sum,0,sizeof(sum));
71         for(int i=0;i<j-1;i++)
72         {
73             l=Fin(line[i].lx,top);
74             r=Fin(line[i].rx,top)-1;
75             if(r>=l)update(1,0,top-1,l,r,line[i].s);
76             answer+=sum[1]*(line[i+1].y-line[i].y);
77         }
78         printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T,answer);
79     }
80     return 0;
81 }

 

 

posted @ 2012-10-30 21:04  诺小J  阅读(177)  评论(0编辑  收藏  举报