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 }