http://acm.pku.edu.cn/JudgeOnline/problem?id=1151
//离散化 + 线段树 + 扫描线
//本题与poj 1177 picture 极相似
//与 1177 不同的是本题中的坐标是浮点
//类型的故不能将坐标直接离散.我们必须为它们建立一个对应关系,用一个整数去对应一个浮点数
1
#include<iostream>
2
#include<algorithm>
3
#define MAXN 205
4
using namespace std;
5![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
struct line
7![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
double x;
9
double y1,y2;
10
int flag;
11
bool operator<( const line &a )
12![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13
return x<a.x;
14
}
15
};
16![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
17
struct segment_tree
18![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
19
int L,R;
20
double len;
21
int cover;
22
};
23![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
24
struct point
25![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
26
double y;
27
int num;
28
bool operator<( const point &a )
29![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
30
return y<a.y;
31
}
32
};
33
segment_tree tree[MAXN*4];
34
point Xpoint[MAXN],Ypoint[MAXN];
35
line yline[MAXN];
36
int Xpost[MAXN][2],Ypost[MAXN][2];
37![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
38
void make_tree( int v, int l, int r )
39![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
40
int mid;
41
tree[v].L=l;
42
tree[v].R=r;
43
tree[v].len=0;
44
tree[v].cover=0;
45
if( r-l>1 )
46![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
47
mid=( l+r )>>1;
48
make_tree( v<<1, l, mid );
49
make_tree( (v<<1)+1, mid, r );
50
}
51
}
52![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
53
void getlen( int v )
54![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
55
if( tree[v].cover>0 )
56
tree[v].len=Ypoint[tree[v].R].y-Ypoint[tree[v].L].y;
57
else if( tree[v].R-tree[v].L==1 )
58
tree[v].len=0;
59
else tree[v].len=tree[v<<1].len+tree[(v<<1)+1].len;
60
}
61![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
62
void update( int v, int l, int r, int flag )
63![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
64
int mid;
65
if( tree[v].L==l && tree[v].R==r )
66![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
67
tree[v].cover+=flag;
68
getlen( v );
69
return ;
70
}
71
mid=( tree[v].L+tree[v].R )>>1;
72
if( mid>=r ) update( v<<1, l, r, flag );
73
else if( mid<=l )update( (v<<1)+1, l, r, flag );
74
else
75![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
76
update( v<<1, l, mid, flag );
77
update( (v<<1)+1, mid, r, flag );
78
}
79
getlen( v );
80
}
81![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
82
int main( )
83![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
84
int n,i,t1,t2,cas=0;
85
double x1,x2,y1,y2;
86
while( scanf("%d",&n) && n )
87![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
88
for( i=0; i<n; i++ )
89![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
90
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
91
t1=i<<1;t2=(i<<1)+1;
92
yline[t1].x=x1,yline[t2].x=x2;
93
yline[t1].flag=1;yline[t2].flag=-1;
94
Ypoint[t1].y=y1;Ypoint[t2].y=y2;
95
Ypoint[t1].num=-(i+1);Ypoint[t2].num=i+1;
96
Xpoint[t1].y=x1;Xpoint[t2].y=x2;
97
Xpoint[t1].num=-(i+1);Xpoint[t2].num=i+1;
98
}
99
sort( Xpoint, Xpoint+(n<<1) );
100
sort( Ypoint, Ypoint+(n<<1) );
101
sort( yline, yline+(n<<1) );
102
for( i=0; i<(n<<1); i++ )
103![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
104
if( Xpoint[i].num<0 )Xpost[-Xpoint[i].num-1][0]=i;
105
else Xpost[Xpoint[i].num-1][1]=i;
106
}
107
for( i=0; i<(n<<1); i++ )
108![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
109
if( Ypoint[i].num<0 )
110
Ypost[Xpost[-Ypoint[i].num-1][0]][0]=Ypost[Xpost[-Ypoint[i].num-1][1]][0]=i;
111
else Ypost[Xpost[Ypoint[i].num-1][0]][1]=Ypost[Xpost[Ypoint[i].num-1][1]][1]=i;
112
}
113
make_tree( 1, 0, (n<<1)-1 );
114
double ans=0;
115
update( 1, Ypost[0][0], Ypost[0][1], yline[0].flag );
116
for( i=1; i<(n<<1); i++ )
117![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
118
ans+=tree[1].len*( yline[i].x-yline[i-1].x);
119
update( 1, Ypost[i][0], Ypost[i][1], yline[i].flag );
120
}
121
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++cas,ans);
122
}
123
return 0;
124
}
125![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)