codevs 3044 矩形面积求并 || hdu 1542

这个线段树的作用其实是维护一组(1维 平面(?) 上的)线段覆盖的区域的总长度,支持加入/删除一条线段。

线段树只能维护整数下标,因此要离散化。

也可以理解为将每一条处理的线段分解为一些小线段,要求每一条要处理的线段都能这么分解

注意端点,线段树维护的是线段,而查询是端点,可能需要稍微变一下

具体的query方法好像类似标记永久化(?)

感觉不优美啊。。。想了一会并没有想到更好的方法。。。。

codevs:

错误记录:

1.打成unordered_map<int,int>

2.70、75行两个tlen误为len

3.要求保留两位小数

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<tr1/unordered_map>
 4 using namespace std;
 5 using namespace tr1;
 6 struct Q
 7 {
 8     int x1,x2;double y1,y2,tx1,tx2;
 9 }q[101];
10 struct QQ
11 {
12     int l,r;double h;int fl;
13     friend bool operator<(const QQ &a,const QQ &b)    {return a.h<b.h;}
14 }qq[202];
15 double tt[202];
16 unordered_map<double,int> ma;
17 int len,tlen;double ans;
18 int n;
19 namespace SegT
20 {
21 #define lc (num<<1)
22 #define rc (num<<1|1)
23 #define mid (l+((r-l)>>1))
24 //[l,r]表示点l到点r+1之间的线段
25     int cover[2010];double dat[2010];
26     int L,R,x;
27     void build(int l,int r,int num)
28     {
29         cover[num]=0;dat[num]=0;
30         if(l!=r)    build(l,mid,lc),build(mid+1,r,rc);
31     }
32     void addx(int l,int r,int num)
33     {
34         if(L<=l&&r<=R)
35         {
36             cover[num]+=x;
37             if(cover[num])    dat[num]=tt[r+1]-tt[l];
38             else    dat[num]=dat[lc]+dat[rc];
39             return;
40         }
41         if(L<=mid)    addx(l,mid,lc);
42         if(mid<R)    addx(mid+1,r,rc);
43         if(cover[num])    dat[num]=tt[r+1]-tt[l];
44         else    dat[num]=dat[lc]+dat[rc];
45     }
46 #undef lc
47 #undef rc
48 #undef mid
49 }
50 int main()
51 {
52     int i;
53     while(1)
54     {
55         scanf("%d",&n);len=tlen=0;ans=0;ma.clear();
56         if(n==0)    break;
57         for(i=1;i<=n;i++)
58         {
59             scanf("%lf%lf%lf%lf",&q[i].tx1,&q[i].y1,&q[i].tx2,&q[i].y2);
60             tt[++tlen]=q[i].tx1;tt[++tlen]=q[i].tx2;
61         }
62         sort(tt+1,tt+tlen+1);tlen=unique(tt+1,tt+tlen+1)-tt-1;
63         for(i=1;i<=tlen;i++)    ma[tt[i]]=i;
64         for(i=1;i<=n;i++)    q[i].x1=ma[q[i].tx1],q[i].x2=ma[q[i].tx2]-1;
65         for(i=1;i<=n;i++)
66         {
67             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y1,1};
68             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y2,-1};
69         }
70         sort(qq+1,qq+len+1);SegT::build(1,tlen-1,1);
71         for(i=1;i<=len;i++)
72         {
73             ans+=SegT::dat[1]*(qq[i].h-qq[i-1].h);
74             SegT::L=qq[i].l;SegT::R=qq[i].r;SegT::x=qq[i].fl;
75             SegT::addx(1,tlen-1,1);
76         }
77         printf("%.2lf\n",ans);
78     }
79     return 0;
80 }

hdu

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<tr1/unordered_map>
 4 using namespace std;
 5 using namespace tr1;
 6 struct Q
 7 {
 8     int x1,x2;double y1,y2,tx1,tx2;
 9 }q[101];
10 struct QQ
11 {
12     int l,r;double h;int fl;
13     friend bool operator<(const QQ &a,const QQ &b)    {return a.h<b.h;}
14 }qq[202];
15 double tt[202];
16 unordered_map<double,int> ma;
17 int len,tlen;double ans;
18 int n;
19 namespace SegT
20 {
21 #define lc (num<<1)
22 #define rc (num<<1|1)
23 #define mid (l+((r-l)>>1))
24 //[l,r]表示点l到点r+1之间的线段
25     int cover[2010];double dat[2010];
26     int L,R,x;
27     void build(int l,int r,int num)
28     {
29         cover[num]=0;dat[num]=0;
30         if(l!=r)    build(l,mid,lc),build(mid+1,r,rc);
31     }
32     void addx(int l,int r,int num)
33     {
34         if(L<=l&&r<=R)
35         {
36             cover[num]+=x;
37             if(cover[num])    dat[num]=tt[r+1]-tt[l];
38             else    dat[num]=dat[lc]+dat[rc];
39             return;
40         }
41         if(L<=mid)    addx(l,mid,lc);
42         if(mid<R)    addx(mid+1,r,rc);
43         if(cover[num])    dat[num]=tt[r+1]-tt[l];
44         else    dat[num]=dat[lc]+dat[rc];
45     }
46 #undef lc
47 #undef rc
48 #undef mid
49 }
50 int main()
51 {
52     int i,T=0;
53     while(1)
54     {
55         scanf("%d",&n);len=tlen=0;ans=0;ma.clear();
56         if(n==0)    break;
57         for(i=1;i<=n;i++)
58         {
59             scanf("%lf%lf%lf%lf",&q[i].tx1,&q[i].y1,&q[i].tx2,&q[i].y2);
60             tt[++tlen]=q[i].tx1;tt[++tlen]=q[i].tx2;
61         }
62         sort(tt+1,tt+tlen+1);tlen=unique(tt+1,tt+tlen+1)-tt-1;
63         for(i=1;i<=tlen;i++)    ma[tt[i]]=i;
64         for(i=1;i<=n;i++)    q[i].x1=ma[q[i].tx1],q[i].x2=ma[q[i].tx2]-1;
65         for(i=1;i<=n;i++)
66         {
67             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y1,1};
68             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y2,-1};
69         }
70         sort(qq+1,qq+len+1);SegT::build(1,tlen-1,1);
71         for(i=1;i<=len;i++)
72         {
73             ans+=SegT::dat[1]*(qq[i].h-qq[i-1].h);
74             SegT::L=qq[i].l;SegT::R=qq[i].r;SegT::x=qq[i].fl;
75             SegT::addx(1,tlen-1,1);
76         }
77         printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T,ans);
78     }
79     return 0;
80 }
View Code
posted @ 2018-04-09 22:26  hehe_54321  阅读(121)  评论(0编辑  收藏  举报
AmazingCounters.com