网上这题好像没有用二维线段树做的,今天写一个试了试。 171MS,还行。
用G++提交的,C++一直
#include<iostream> #include<algorithm> #include<map> #include<iomanip> using namespace std; map<double,int> mx; map<int,double> subx; map<double,int> my; map<int,double> suby; double tx[250]; double ty[250]; struct rec { double x1; double y1; double x2; double y2; }p[110]; struct sub_tree { int left; int right; int mid; int flag; double total; }; struct up_tree { int left; int right; int mid; int flag; double total; struct sub_tree sub[200*4]; }up[200*4]; int n; int countt; int t1,t2; //上树和下树的最大值,即x,y坐标的最大个数 void create_up_tree(int l,int r,int now); void create_sub_tree(int l,int r,int upid,int now); void update_up(int l,int r,int yl,int yr,int now); void update_sub(int l,int r,int upid,int now); int T; int main() { T=1; while(cin>>n,n) { mx.clear(); my.clear(); countt=0; for(int i=0;i<n;i++) { cin>>p[i].x1>>p[i].y1>>p[i].x2>>p[i].y2; tx[countt]=p[i].x1; ty[countt++]=p[i].y1; tx[countt]=p[i].x2; ty[countt++]=p[i].y2; } sort(tx,tx+countt); sort(ty,ty+countt); t1=0,t2=0; for(int i=0;i<countt;i++) { if(!mx[tx[i]]) { subx[t1]=tx[i]; mx[tx[i]]=t1++; } if(!my[ty[i]]) { suby[t2]=ty[i]; my[ty[i]]=t2++; } } create_up_tree(0,205,1); /* for(i=0;i<n;i++) { cout<<mx[p[i].x1]<<" "<<my[p[i].y1]<<" "<<mx[p[i].x2]<<" "<<my[p[i].y2]<<endl; } for(i=0;i<n;i++) { cout<<subx[mx[p[i].x1]]<<" "<<suby[my[p[i].y1]]<<" "<<subx[mx[p[i].x2]]<<" "<<suby[my[p[i].y2]]<<endl; } */ for(int i=0;i<n;i++) { if(p[i].x1==p[i].x2 || p[i].y1==p[i].y2) continue; update_up( mx[p[i].x1] , mx[p[i].x2] , my[p[i].y1] , my[p[i].y2] ,1); } cout<<"Test case #"<<T++<<endl; cout<<"Total explored area: "<<fixed<<setprecision(2)<<up[1].total<<endl<<endl; } return 0; } void create_up_tree(int l,int r,int now) { up[now].left=l; up[now].right=r; up[now].total=0; // up[now].flag=0; create_sub_tree(0,205,now,1); if(l+1==r) return ; int mid=(l+r)>>1; up[now].mid=mid; create_up_tree(l,mid,now*2); create_up_tree(mid,r,now*2+1); } void create_sub_tree(int l,int r,int upid,int now) { up[upid].sub[now].left=l; up[upid].sub[now].right=r; up[upid].sub[now].total=0; // up[upid].sub[now].flag=0; if(l+1==r) return ; int mid=(l+r)>>1; up[upid].sub[now].mid=mid; create_sub_tree(l,mid,upid,now*2); create_sub_tree(mid,r,upid,now*2+1); } void update_up(int l,int r,int yl,int yr,int now) { if(l+1==r && l==up[now].left && r==up[now].right) { update_sub(yl,yr,now,1); up[now].total= (subx[r]-subx[l]) * up[now].sub[1].total ; return ; } if(up[now].mid>=r) { update_up(l,r,yl,yr,now*2); up[now].total=up[now*2].total+up[now*2+1].total; } else if(up[now].mid<=l) { update_up(l,r,yl,yr,now*2+1); up[now].total=up[now*2].total+up[now*2+1].total; } else { update_up(l,up[now].mid,yl,yr,now*2); update_up(up[now].mid,r,yl,yr,now*2+1); up[now].total=up[now*2].total+up[now*2+1].total; } } void update_sub(int l,int r,int upid,int now) { if(l+1==r && l==up[upid].sub[now].left && r==up[upid].sub[now].right) { up[upid].sub[now].total=suby[r]-suby[l]; return ; } if(up[upid].sub[now].mid>=r) { update_sub(l,r,upid,now*2); up[upid].sub[now].total=up[upid].sub[now*2].total+up[upid].sub[now*2+1].total; } else if(up[upid].sub[now].mid<=l) { update_sub(l,r,upid,now*2+1); up[upid].sub[now].total=up[upid].sub[now*2].total+up[upid].sub[now*2+1].total; } else { update_sub(l,up[upid].sub[now].mid,upid,now*2); update_sub(up[upid].sub[now].mid,r,upid,now*2+1); up[upid].sub[now].total=up[upid].sub[now*2].total+up[upid].sub[now*2+1].total; } }