网上这题好像没有用二维线段树做的,今天写一个试了试。 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;
}
}