hdu 1542--线段树扫描线

http://acm.hdu.edu.cn/showproblem.php?pid=1542

题意:矩形面积并
思路:浮点数先要离散化;然后把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用cnt表示该区间下边比上边多几个,sum代表该区间内被覆盖的线段的长度总和
这里线段树的一个结点并非是线段的一个端点,而是该端点和下一个端点间的线段,所以题目中r+1,r-1的地方可以自己好好的琢磨一下

复制代码
View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 #define maxn 22222
 7 #define lson l,m,rt<<1
 8 #define rson m+1,r,rt<<1|1
 9 double sum[maxn<<2],X[maxn];
10 int cnt[maxn<<2];
11 struct node{
12     double l,r,h;
13     int f;
14     node(){}
15     node(double a,double b,double c,int d):l(a),r(b),h(c),f(d){}
16     bool operator <(const node &cmp) const{
17         return h<cmp.h;
18     }
19 }ss[maxn];
20 void Pushup(int l,int r,int rt)
21 {
22     if(cnt[rt]) sum[rt]=X[r+1]-X[l];
23     else if(l==r) sum[rt]=0;
24     else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
25 }
26 void update(int L,int R,int c,int l,int r,int rt)
27 {
28     if(L<=l&&r<=R)
29     {
30         cnt[rt]+=c;
31         Pushup(l,r,rt);
32         return;
33     }
34     int m=(l+r)>>1;
35     if(L<=m) update(L,R,c,lson);
36     if(R>m) update(L,R,c,rson);
37     Pushup(l,r,rt);
38 }
39 int Bin(double k,int n,double *X)
40 {
41     int l=0,r=n-1;
42     while(l<=r)
43     {
44         int m=(l+r)>>1;
45         if(X[m]==k) return m;
46         else if(X[m]<k) l=m+1;
47         else r=m-1;
48     }
49     return -1;
50 }
51 int main()
52 {
53     int t,i,cas=1;
54     while(~scanf("%d",&t),t)
55     {
56         int m=0;
57         while(t--)
58         {
59             double a,b,c,d;
60             scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
61             X[m]=a;
62             ss[m++]=node(a,c,b,1);
63             X[m]=c;
64             ss[m++]=node(a,c,d,-1);
65         }
66         sort(X,X+m);
67         sort(ss,ss+m);
68         int n=1;
69         for(i=1;i<m;i++)
70             if(X[i]!=X[i-1])
71                 X[n++]=X[i];
72         memset(sum,0,sizeof(sum));
73         memset(cnt,0,sizeof(cnt));
74         double ret=0;
75         for(i=0;i<m-1;i++)
76         {
77             int l=Bin(ss[i].l,n,X);
78             int r=Bin(ss[i].r,n,X)-1;
79             if(l<=r)
80                 update(l,r,ss[i].f,0,n-1,1);
81             ret+=sum[1]*(ss[i+1].h-ss[i].h);
82         }
83         printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++,ret);
84     }
85     return 0;
86 }
复制代码

 

posted on 2013-02-19 13:50  acoderworld  阅读(91)  评论(0)    收藏  举报

< 2025年7月 >
29 30 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 1 2
3 4 5 6 7 8 9

导航

统计

点击右上角即可分享
微信分享提示